campo-sirio/sv/sv1100.cpp
guy 4f569ec3c4 Patch level : 2.0 480
Files correlati     : sv0.exe sv1.exe sv2.exe sv0400a.msk sv1100a.frm sv1100b.frm
Ricompilazione Demo : [ ]
Commento            :

GF20028
La selezione per omaggi non può essere effettuata

ATTENZIONE: Ci risulta che il bottone omaggi sia sempre selezionabile.
Inoltre abilitando gli omaggi nei parametri statistiche, questi
vengono stampati correttamente.  Necessita segnalazione piu' chiara.

GF20029
La stampa schede di vendita arrotonda glie importi all'intero.


git-svn-id: svn://10.65.10.50/trunk@11194 c028cbd2-c16b-5b4b-a496-9718f37d4682
2003-05-29 08:05:53 +00:00

1400 lines
37 KiB
C++
Executable File
Raw Blame History

#include <applicat.h>
#include <config.h>
#include <currency.h>
#include <form.h>
#include <msksheet.h>
#include <printer.h>
#include <progind.h>
#include <recarray.h>
#include <tabutil.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);
static bool valuta_handler(TMask_field& f, KEY k);
static bool realfield_handler(TMask_field& f, KEY k);
static bool cambio_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::valuta_handler(TMask_field& f, KEY key)
{
if (key == K_TAB && f.to_check(key, TRUE))
{
TMask& m = f.mask();
const TString& val = f.get();
const bool full = val.not_empty() && val != TCurrency::get_firm_val();
if (full)
{
TEdit_field& dc = m.efield(F_DATACAMBIO);
if (dc.empty()) // Inizializza data cambio se assente
{
const TDate oggi(TODAY);
dc.set(oggi.string());
}
if (f.focusdirty())
{
dc.set_dirty();
dc.check(RUNNING_CHECK); // Forza ricerca cambio
if (m.get(F_CAMBIO).empty())
{
TCursor& cur = *dc.browse()->cursor();
if (cur.items() == 0) // Uso cambio standard
{
const TRectype& rec = cache().get("%VAL", val);
dc.set(rec.get("D0"));
m.set(F_CAMBIO, rec.get("S4"));
m.set(F_CONTROEURO, rec.get("B1"));
}
}
}
}
else
{
m.reset(F_DATACAMBIO);
m.reset(F_CAMBIO);
m.reset(F_CONTROEURO);
}
}
return TRUE;
}
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::realfield_handler(TMask_field& f, KEY k)
{
if (k == K_F9)
{
TMask& m = f.mask();
const TSheet_field& s = *m.get_sheet();
TRelation rel(s.dlg() == F_SINTETICA ? LF_DOC : LF_RIGHEDOC);
TRelation_description rd(rel);
if (rd.choose_field(f.get()))
{
f.set(rd.field_name());
TEdit_field& head = m.efield(S_HEAD);
TParagraph_string para(rd.field_desc(), head.size());
head.set(para.get(0));
m.set(S_DESCR, rd.field_desc());
if (rd.field_type() == _realfld)
{
const int decimals = rel.curr().ndec(rd.field_name());
const int length = rel.curr().length(rd.field_name());
m.set(S_IMPORTO, (decimals <= 3 && length >= 6)? "X" : "");
}
else
return f.error_box("E' necessario selezionare un campo numerico.");
}
}
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; // Posso aggiungere al massimo otto colonne di stampa
break;
case K_CTRL+K_INS:
s.row(row) = "F"; // Proponi una formula
break;
default:
break;
}
return ok;
}
void TSchede_mask::sheet2ini(short id)
{
TSheet_field& sheet = sfield(id);
TString_array& arr = sheet.rows_array();
const char* field = id == F_SINTETICA ? "SynField" : "DetField";
const char* head = id == F_SINTETICA ? "SynHead" : "DetHead";
TConfig ini(CONFIG_STUDIO, "sv1100");
for (int r = arr.last(); r >= 0; r--)
{
TToken_string& row = arr.row(r);
ini.set(field, row.get(1), 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";
TRelation rel(id == F_SINTETICA ? LF_DOC : LF_RIGHEDOC);
const TRectype& rec = rel.curr();
TRelation_description rd(rel);
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 = rec.exist(str) ? "C" : "F";
row.add(str);
row.add(ini.get(head, NULL, r));
if (row[0] == 'C')
{
row.add(rd.get_field_description(str));
if (rec.type(str) == _realfld)
row.add(rec.ndec(str) <= 3 ? "X" : "");
}
else
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);
sm.set_handler(S_REALFIELD, realfield_handler);
}
TSchede_mask::TSchede_mask()
: TSelection_mask("sv1100a")
{
set_handler(F_TODATE, date_handler);
set_handler(F_TONUM, num_handler);
set_handler(F_VALUTA, valuta_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);
void init_pictures(const TMask& msk);
TSchede_form(const char* n);
virtual ~TSchede_form() { }
};
TSchede_form::TSchede_form(const char* n)
: TForm(n)
{
}
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(1);
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(2);
if (str.blank())
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);
TForm::genera_intestazioni(odd_page, hh-1);
}
void TSchede_form::init_pictures(const TMask& msk)
{
const TPrint_section& head = section('H', odd_page);
const int hh = head.height();
TForm::genera_intestazioni(odd_page, hh-1);
const char tipo_stampa = msk.get(F_TIPO)[0];
TSheet_field& sheet = msk.sfield(tipo_stampa == 'D' ? F_DETTAGLIATA : F_SINTETICA);
const int imppos = sheet.cid2index(S_IMPORTO);
const int rfpos = sheet.cid2index(S_REALFIELD);
const int ftpos = sheet.cid2index(S_FIELDTYPE);
TPrint_section& body = section('B', odd_page);
const int campi = sheet.items()+2;
const TCurrency valuta(ZERO, msk.get(F_VALUTA));
TRectype rec(tipo_stampa == 'D' ? LF_RIGHEDOC : LF_DOC);
TString16 pic;
for (int c = 0; c < campi; c++)
{
TForm_item& fi = body.find_field(FF_FIRSTCOLUMN+c);
bool importo = TRUE;
if (c > 1)
importo = sheet.row(c-2).get_char(imppos) > ' ';
if (importo)
{
pic.format(".%d", valuta.decimals());
fi.set_picture(pic);
}
else
{
if (c > 1 && sheet.row(c-2).get_char(ftpos) == 'C')
{
pic.format(".%d",rec.ndec(sheet.row(c-2).get(rfpos)));
fi.set_picture(pic);
}
}
}
}
///////////////////////////////////////////////////////////
// Main app
///////////////////////////////////////////////////////////
class TStampa_schede : public TSkeleton_application
{
char _clifo; // <C>lienti o <F>ornitori
char _tipo; // <D>ettagliata o <S>intetica
char _sort; // <F>attura o <A>rticolo
char _prov; // <P>rovvisori o <D>efinitivi
bool _peragenti; // Stampa per agenti
bool _perageart; // Stampa per agenti ma ordinata per Articolo, Cliente, documento
bool _provvart; // Stampa solo righe articolo con provvigione
TString _curagente; // Codice e descrizione agente corrente
TDate _fromdate, _todate; // Date limite
TString _fromnum, _tonum; // Numerazioni limite
TString _tipodoc; // Tipo documento limite
TArray _totali; // Totali complessivi
TArray _totriga; // Totali di riga
TArray _totage; // Totali per agente
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 void main_loop();
virtual bool create();
virtual bool destroy();
protected:
void put_real(TRectype& tab, int index, real val, bool importo, const TExchange& fc, const TExchange& tc);
void fill_key(TRectype& tab, const TDocumento& doc, const bool ageart = FALSE);
void fill_key(TRectype& tab, const TRiga_documento& rdoc, const bool ageart = FALSE);
static bool filtra_doc_per_stat(const TRelation* rel);
public:
// 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, const bool ageart = FALSE);
void update_totriga(const TRectype& tab);
void update_totage(const TRectype& tab);
void fill_totriga(TRectype& tab);
void fill_tot(TRectype& tab);
void fill_totage(TRectype& tab);
void fill_codart(TRectype& tab);
void fill_codcli(TRectype& tab);
bool write_tab(TLocalisamfile& tab) const;
bool write_totali_per_articolo(TLocalisamfile& tab);
bool write_artcli_descrizioni(TLocalisamfile& tab);
bool stampa_clienti() const { return _clifo == 'C'; }
bool stampa_fornitori() const { return _clifo == 'F'; }
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_per_agente() const { return _peragenti; }
bool stampa_per_ageart() const { return _perageart; }
long clifo2index(TCursor_sheet& clifosheet, long codcf);
bool raggruppa_articoli(TCursor& cur, TProgind* pi, bool last_clifo);
bool stampa_clifo(TCursor& cur, const TString& ragsoc, bool last_clifo);
bool stampa_selezione(TCursor& clifocur, const TSheet& clifosheet, const TString& filter);
};
void TStampa_schede::put_real(TRectype& tab, int index, real val, bool importo,
const TExchange& fc, const TExchange& tc)
{
char erre[4]; sprintf(erre, "R%d", index);
if (importo)
{
TCurrency cur(val, fc);
cur.change_value(tc);
val = cur.get_num();
}
tab.put(erre, val);
// Se non <20> un importo, non va totalizzato (ad esempio le quantita...)
if (importo)
{
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, const bool ageart)
{
tab.zero();
tab.put("COD", "PRN");
const TCli_for& clifo = doc.clifor();
tab.put("S8", clifo.tipo());
tab.put("I8", clifo.codice());
if (ageart)
tab.put("S4", doc.get("CODAG"));
TString16 str;
TString80 key;
if (ageart)
key.format("%c%7ld", clifo.tipo(), clifo.codice());
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, const bool ageart)
{
fill_key(tab, rdoc.doc(), ageart);
_lastkey = tab.get("S0");
_lastkey.left_just(20);
if (stampa_per_articolo() || ageart)
{
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;
// Codice valuta del documento
const TExchange fc(doc.head());
// Codice valuta di stampa
const TString& codval = _mask->get(F_VALUTA);
const real cambio = _mask->get(F_CAMBIO);
const exchange_type tipocambio = _mask->get_bool(F_CONTROEURO) ? _exchange_contro : _exchange_base;
const TExchange tc(codval, cambio, tipocambio);
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);
const bool is_nota_credito = doc.tipo().nota_credito();
real bs = doc.basesconto();
real td = doc.totale_doc();
if (is_nota_credito)
{
bs = -bs;
td = -td;
}
put_real(tab, 0, bs, TRUE, fc, tc);
put_real(tab, 1, td, TRUE, fc, tc);
TSheet_field& sheet = _mask->sfield(F_SINTETICA);
const int fldpos = sheet.cid2index(S_FIELD);
const int imppos = sheet.cid2index(S_IMPORTO);
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(fldpos);
if (src.blank())
break;
const bool importo = row.get_char(imppos) > ' ';
real val = doc.get(src);
if (is_nota_credito)
val = -val;
put_real(tab, r+2, val, importo, fc, tc);
}
return TRUE;
}
bool TStampa_schede::fill_rdoc(TRectype& tab, const TRiga_documento& rdoc, const bool ageart)
{
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;
// Codice valuta del documento
const TExchange fc(doc.head());
// Codice valuta di stampa
const TString& codval = _mask->get(F_VALUTA);
const real cambio = _mask->get(F_CAMBIO);
const exchange_type tipocambio = _mask->get_bool(F_CONTROEURO) ? _exchange_contro : _exchange_base;
const TExchange tc(codval, cambio, tipocambio);
fill_key(tab, rdoc, ageart);
TString descr(80);
if (ageart)
{
descr << "*** Doc." << doc.numerazione();
descr << '/' << doc.numero();
descr << " del " << doc.data();
}
else
{
if (stampa_per_articolo())
{
descr << doc.numerazione();
descr << ' ' << doc.numero();
descr << "," << doc.data();
descr << ':' << rdoc.get(RDOC_DESCR);
} else {
descr << rdoc.get(RDOC_CODART) << ' ';
descr << rdoc.get(RDOC_DESCR);
}
}
descr.cut(50);
tab.put("S1", descr);
const bool is_nota_credito = doc.tipo().nota_credito();
real ins = rdoc.importo(TRUE, FALSE);
real ils = rdoc.importo(TRUE, TRUE);
if (is_nota_credito)
{
ins = -ins;
ils = -ils;
}
put_real(tab, 0, ins, TRUE, fc, tc); // importo netto scontato
put_real(tab, 1, ils, TRUE, fc, tc); // importo lordo scontato
TSheet_field& sheet = _mask->sfield(F_DETTAGLIATA);
TString_array& arr = sheet.rows_array();
const int fldpos = sheet.cid2index(S_FIELD);
const int imppos = sheet.cid2index(S_IMPORTO);
TString16 src;
for (int r = 0; r < arr.items(); r++)
{
TToken_string& row = arr.row(r);
src = row.get(fldpos);
if (src.blank())
break;
const bool importo = row.get_char(imppos) > ' ';
real val = rdoc.get(src);
if (is_nota_credito)
val = -val;
put_real(tab, r+2, val, importo, fc, tc);
}
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)
{
TString80 descr;
tab.zero();
tab.put("COD", "PRN");
tab.put("CODTAB", ++_progressivo);
_lastkey.overwrite("9999", _lastkey.len()-4);
tab.put("S0", _lastkey);
if (stampa_per_articolo())
{
descr= "Totale articolo " ;
descr << _lastkey.left(20);
} else {
TDate ddoc;
ddoc.set_year(atoi(_lastkey.left(4)));
ddoc.set_month(atoi(_lastkey.mid(4,2)));
ddoc.set_day(atoi(_lastkey.mid(6,2)));
descr << "Totale documento " << _lastkey.mid(8,4) ;
descr << ' ' << atoi(_lastkey.mid(12,4));
descr << " del " << ddoc;
}
tab.put("S1", descr);
tab.put("B8", TRUE); // Riga totale
TSheet_field& sheet = _mask->sfield(stampa_dettagliata() ? F_DETTAGLIATA : F_SINTETICA);
TString_array& arr = sheet.rows_array();
const int imppos = sheet.cid2index(S_IMPORTO);
for (int r = _totriga.last(); r >= 0; r--)
{
const bool importo = r > 1 ? arr.row(r-2).get_char(imppos) > ' ' : TRUE;
char erre[4]; sprintf(erre, "R%d", r);
tab.put(erre, importo ? (real&)_totriga[r] : ZERO);
}
}
void TStampa_schede::fill_codart(TRectype& tab)
{
TLocalisamfile& anamag = _form->relation()->lfile(LF_ANAMAG);
TString s, ca;
s = _lastkey.left(20);
ca = tab.get("S4");
tab.zero();
tab.put("COD", "PRN");
tab.put("CODTAB", ++_progressivo);
tab.put("S0", s);
anamag.put("CODART",s);
s.insert("@B");
s.trim();
if (anamag.read() == NOERR)
s << " " << anamag.get("DESCR");
tab.put("S1", s);
tab.put("S4", ca); // Riporta il codice agente
}
void TStampa_schede::fill_codcli(TRectype& tab)
{
TLocalisamfile& clifo = _form->relation()->lfile(LF_CLIFO);
TString s,ca;
ca = tab.get("S4");
s = _lastkey.left(28); // CODART + TIPOCF + CODCF
tab.zero();
tab.put("COD", "PRN");
tab.put("CODTAB", ++_progressivo);
tab.put("S0", s);
s.ltrim(20);
const char t = s[0];
const long c = atol(s.right(7));
clifo.put("TIPOCF", t); clifo.put("CODCF", c);
s = t=='C' ? "Cliente " : "Fornitore " ;
s << c << " ";
if (clifo.read() == NOERR)
s << clifo.get("RAGSOC");
s.strip_d_spaces();
tab.put("S1", s);
tab.put("S4", ca); // Riporta il codice agente
}
void TStampa_schede::fill_tot(TRectype& tab)
{
tab.zero();
tab.put("COD", "PRN");
tab.put("CODTAB", ++_progressivo);
tab.put("S0", "yyyyyyyy"); // Si assicura che sia l'ultima prima dell'agente
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::write_artcli_descrizioni(TLocalisamfile& tab)
{
bool ok = TRUE;
TRectype& curtab = tab.curr();
const TRecfield key(curtab, "S0");
const TRecfield art(curtab, "S0", 0, 19);
TString last_art;
_lastkey = "";
for (int err = tab.first(); err == NOERR && ok; err = tab.next())
{
if (_lastkey.not_empty())
if (_lastkey.compare((const char*)key, 28) != 0) // Cambio articolo o cliente
{
const TRecnotype pos = tab.recno();
if (last_art != (const char*)art)
{
fill_codart(curtab);
ok = write_tab(tab);
}
// <20> per forza un cambio codcf
fill_codcli(curtab);
ok = write_tab(tab);
tab.put("S0", _lastkey);
if (tab.read() == NOERR)
{
tab.put("B8", TRUE);
tab.rewrite();
}
tab.readat(pos);
}
_lastkey = (const char*)key;
last_art = (const char*)art;
}
if (ok && _lastkey.not_empty())
{
tab.put("B8",TRUE); tab.rewrite();
fill_codart(curtab);
ok = write_tab(tab);
fill_codcli(curtab);
ok = write_tab(tab);
}
return ok;
}
void TStampa_schede::update_totage(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*)_totage.objptr(r);
if (tot == NULL)
_totage.add(val, r);
else
*tot += val;
}
}
void TStampa_schede::fill_totage(TRectype& tab)
{
tab.zero();
tab.put("COD", "PRN");
tab.put("CODTAB", ++_progressivo);
TString80 descr;
descr << "Totale Agente " << _curagente;
descr.cut(50);
tab.put("S0", "zzzzzzzz"); // Mi assicuro che sia l'ultima riga
tab.put("S1", descr);
tab.put("B8", TRUE); // Riga totale
TSheet_field& sheet = _mask->sfield(stampa_dettagliata() || stampa_per_ageart() ? F_DETTAGLIATA : F_SINTETICA);
TString_array& arr = sheet.rows_array();
const int imppos = sheet.cid2index(S_IMPORTO);
for (int r = _totage.last(); r >= 0; r--)
{
const bool importo = r > 1 ? arr.row(r-2).get_char(imppos) > ' ' : TRUE;
char erre[4]; sprintf(erre, "R%d", r);
tab.put(erre, importo ? (real&)_totage[r] : ZERO);
}
}
bool TStampa_schede::raggruppa_articoli(TCursor& cur, TProgind* pi, bool last_clifo)
{
const long items = cur.items();
cur.file().set_curr(new TDocumento);
TRectype& curtab = _form->cursor()->curr();
TLocalisamfile& tab = _form->relation()->lfile();
TDocumento& doc = (TDocumento&)cur.file().curr();
bool can_print = TRUE;
// Scorre i documenti del cliente corrente
for (cur = 0; cur.pos() < items && can_print; ++cur)
{
if (pi->iscancelled())
{
can_print = FALSE;
break;
}
// Scorre le righe del documento corrente
for (int r = doc.physical_rows(); r > 0 && can_print; r--)
{
const TRiga_documento& rdoc = doc[r];
if (rdoc.is_articolo())
{
bool fill = TRUE;
if (_provvart)
fill = !rdoc.provvigione().is_zero();
if (fill && fill_rdoc(curtab, rdoc, TRUE))
{
can_print = write_tab(tab);
if (can_print)
update_totage(curtab);
}
}
}
}
if (can_print && last_clifo)
{
// Scrive le righe che mancano
write_artcli_descrizioni(tab);
// Totale agente
fill_totage(curtab);
can_print = write_tab(tab);
}
return can_print;
}
bool TStampa_schede::stampa_clifo(TCursor& cur, const TString& ragsoc, bool last_clifo)
{
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);
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;
TForm_item& tit = _form->find_field('H',odd_page,FF_TITOLO);
tit.set(stampa_clienti() ? "clienti" : "fornitori");
TForm_item& age = _form->find_field('H',odd_page,FF_AGENTE);
if (stampa_per_agente())
{
age.show();
age.set(_curagente);
}
else
age.hide();
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);
if (can_print && stampa_per_agente())
update_totage(curtab);
}
}
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 (can_print)
{
if (stampa_per_documento())
update_totriga(curtab);
if (stampa_per_agente())
update_totage(curtab);
}
}
}
if (can_print && _totriga.items() > 0)
{
fill_totriga(curtab);
can_print = write_tab(*tab);
}
}
}
if (can_print && tab->items() > 0)
{
if (can_print && stampa_per_articolo())
can_print = write_totali_per_articolo(*tab);
if (can_print)
{
fill_tot(curtab);
can_print = write_tab(*tab);
}
if (can_print && stampa_per_agente() && last_clifo)
{
fill_totage(curtab);
can_print = write_tab(*tab);
}
}
pi.close_modal();
if (can_print && tab->items() > 0)
{
TForm_item& col1 = _form->find_field('B',odd_page,FF_FIRSTCOLUMN);
TForm_item& col2 = _form->find_field('B',odd_page,FF_SECONDCOLUMN);
if (stampa_sintetica())
{
col1.set_col_head("Base sconto");
col2.set_col_head("Totale");
} else {
col1.set_col_head("Netto scontato");
col2.set_col_head("Lordo scontato");
}
_form->init_pictures(*_mask);
_form->print();
}
_form->relation()->replace(new TLocalisamfile(LF_TAB));
return can_print;
}
bool TStampa_schede::filtra_doc_per_stat(const TRelation* rel)
{
const TString16 tipodoc = rel->curr().get(DOC_TIPODOC);
const TRectype& tipo = cache().get("%TIP", tipodoc);
const bool stat = tipo.get_bool("B2");
return stat;
}
bool TStampa_schede::stampa_selezione(TCursor& clifocur, const TSheet& clifosheet,
const TString& filter)
{
const long clifos = clifosheet.items();
long toprint = clifosheet.checked();
if (toprint == 0) toprint = clifos;
const bool all = toprint == clifos;
const long items = clifocur.items();
TString ragsoc;
TRelation rel(LF_DOC);
TRectype rec(LF_DOC);
bool cancel = FALSE;
TProgind *pi = NULL;
// Inizializzazione solo per stampa agenti/articoli/clienti/documenti
if (stampa_per_ageart())
{
TForm_item& tit = _form->find_field('H',odd_page,FF_TITOLO);
tit.set("agenti");
TString header(160);
header = "Preparazione file temporaneo di stampa per l'agente: ";
header << _curagente;
pi = new TProgind(items, header, TRUE, TRUE, 60);
// Sostituisce il file principale
TIsamtempfile* tab = new TIsamtempfile(LF_TAB, "svschede", TRUE,TRUE);
tab->setkey(2);
_form->relation()->replace(tab);
_progressivo = 0;
}
printer().open();
for (clifocur = 0; clifocur.pos() < clifos && toprint > 0 && !cancel; ++clifocur)
{
if (all || clifosheet.checked(clifocur.pos()))
{
const char tipocf = clifocur.curr().get_char(CLI_TIPOCF);
const long codcf = clifocur.curr().get_long(CLI_CODCF);
ragsoc = tipocf == 'C' ? TR("Cliente") : TR("Fornitore");
ragsoc << ' ' << codcf << " - " << clifocur.file().get(CLI_RAGSOC);
if (pi)
pi->addstatus(1L);
rec.put(DOC_TIPOCF, tipocf);
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);
cur.set_filterfunction(filtra_doc_per_stat);
if (cur.items() > 0)
{
cur.freeze();
cancel = stampa_per_ageart() ? !raggruppa_articoli(cur, pi, toprint == 1) : !stampa_clifo(cur, ragsoc, toprint == 1);
cur.freeze(FALSE);
}
toprint--;
}
}
// Stampa scheda agenti suddivisa per articoli/cliente/documento
if (!cancel && stampa_per_ageart())
{
pi->setstatus(items);
_form->init_pictures(*_mask);
if (_form->cursor()->items() > 0)
_form->print();
// Necessario fare il replace per la stampa del prossimo agente
// In modo che venga automaticamente cancellato il precedente file temporaneo
_form->relation()->replace(new TLocalisamfile(LF_TAB));
}
printer().close();
if (pi)
delete pi;
return !cancel;
}
long TStampa_schede::clifo2index(TCursor_sheet& clifosheet, long codcf)
{
long i = -1;
const int codpos = _mask->get_int(SC_SORTCF); // Posizione del codice clifo nello sheet
if (codpos == 1)
{
long a = 0;
long b = clifosheet.items()-1;
while (a <= b)
{
i = (a+b)/2;
const long clifo = clifosheet.row(i).get_long(codpos);
if (clifo == codcf)
break;
if (clifo > codcf)
b = i-1;
else
a = i+1;
}
}
else
{
for (i = clifosheet.items()-1; i >= 0; i--)
{
TToken_string& row = clifosheet.row(i);
long clifo = row.get_long(codpos);
if (clifo == codcf)
break;
}
}
return i;
}
void TStampa_schede::main_loop()
{
TSchede_mask& m = *_mask;
while (m.run() != K_QUIT)
{
_clifo = m.get(SC_CLIFO)[0];
_tipo = m.get(F_TIPO)[0];
_sort = m.get(F_ORDINE)[0];
_prov = m.get(F_PROVVIS)[0];
_peragenti = m.get_bool(F_SORTAGENTI);
_perageart = m.get_bool(F_SORTAGEART);
_provvart = m.get_bool(F_PROVVART);
_fromdate = m.get_date(F_FROMDATE);
_todate = m.get_date(F_TODATE);
_fromnum = m.get(F_FROMNUM);
_tonum = m.get(F_TONUM);
_tipodoc = m.get(F_TIPODOC);
_form = new TSchede_form(_perageart ? "sv1100b" : "sv1100a");
_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 << "\")";
}
if (_tipodoc.not_empty())
{
if (filter.not_empty()) filter << "&&";
filter << '(' << DOC_TIPODOC << "==\"" << _tipodoc << "\")";
}
TCursor_sheet& clifosheet = m.cur_sheet();
TCursor& clifocur = *clifosheet.cursor();
const long clifos = clifocur.items();
long toprint = clifosheet.checked();
const bool all = toprint == 0 || toprint == clifos;
bool cancel = FALSE;
if (stampa_per_agente())
{
TRelation relagenti(LF_AGENTI);
TRectype fromage(LF_AGENTI), toage(LF_AGENTI);
if (m.get(F_DAAGENTE).not_empty())
fromage.put(AGE_CODAGE, m.get(F_DAAGENTE));
if (m.get(F_ADAGENTE).not_empty())
toage.put(AGE_CODAGE, m.get(F_ADAGENTE));
TCursor curagenti(&relagenti, "", 1, &fromage, &toage);
const long ages = curagenti.items();
curagenti.freeze();
const TRectype& recagenti = curagenti.curr();
const int codpos = m.get_int(SC_SORTCF); // Posizione del codice clifo nello sheet
TAssoc_array selection;
if (!all)
{
// Crea la lista degli elementi selezionati dall'utente
for (long i = clifosheet.items()-1; i >= 0; i--)
{
if (clifosheet.checked(i))
{
TString16 codcf = clifosheet.row(i).get(codpos);
selection.add(codcf, NULL);
}
}
}
TRelation rel(LF_DOC);
TRectype rec(LF_DOC);
rec.put(DOC_TIPOCF, m.get_who());
for (curagenti = 0L; curagenti.pos() < ages && !cancel; ++curagenti)
{
_totage.destroy(); // Azzera totali agente
TString filterage(filter);
if (filterage.not_empty()) filterage << "&&";
filterage << '(' << DOC_CODAG << "==\"" << recagenti.get(AGE_CODAGE) << "\")";
TCursor cur(&rel, filterage, 2, &rec, &rec);
cur.set_filterfunction(filtra_doc_per_stat);
const long docs = cur.items();
if (docs > 0)
{
clifosheet.uncheck(-1);
cur.freeze();
for (cur = 0; cur.pos() < docs; ++cur)
{
const TString16 codcf = cur.curr().get(DOC_CODCF);
if (all || selection.is_key(codcf))
{
long i = clifo2index(clifosheet, atol(codcf));
if (i >= 0)
clifosheet.check(i);
}
}
cur.freeze(FALSE);
if (clifosheet.one_checked())
{
_curagente = recagenti.get(AGE_CODAGE);
_curagente << ' ' << recagenti.get(AGE_RAGSOC);
cancel = !stampa_selezione(clifocur, clifosheet, filterage);
}
}
}
}
else
{
_curagente.cut(0);
if (all)
{
TString msg;
msg.format(FR("Attenzione: e' stata selezionata la stampa di tutti i %s!\n"
"Si desidera continuare ugualmente?"),
m.get_who() == 'C' ? TR("clienti") : TR("fornitori"));
cancel = !yesno_box(msg);
}
if (!cancel)
stampa_selezione(clifocur, clifosheet, filter);
}
delete _form;
}
}
bool TStampa_schede::create()
{
open_files(LF_DOC, LF_RIGHEDOC, LF_CONDV, LF_RCONDV, LF_ANAMAG, LF_SCONTI, LF_UMART,
LF_TAB, LF_TABCOM, LF_CLIFO,LF_CFVEN, LF_INDSP, LF_OCCAS, LF_MOVMAG, LF_RMOVMAG,LF_PROVV, 0);
open_files(LF_SVRIEP,LF_SVSTAT,0);
_mask = new TSchede_mask;
return TSkeleton_application::create();
}
bool TStampa_schede::destroy()
{
delete _mask;
return TRUE;
}
int sv1100(int argc, char* argv[])
{
TStampa_schede app;
app.run(argc, argv, "Stampa schede");
return 0;
}