campo-sirio/ca/ca0800.cpp
guy 6dd2e7816f Patch level : 2.2
Files correlati     : ca0
Ricompilazione Demo : [ ]
Commento            :

Aggiunta gestione tabelle di ripartizione


git-svn-id: svn://10.65.10.50/trunk@12563 c028cbd2-c16b-5b4b-a496-9718f37d4682
2004-12-31 09:58:58 +00:00

426 lines
11 KiB
C++
Executable File

#include <automask.h>
#include <recarray.h>
#include <relapp.h>
#include "ca0800a.h"
const char* get_key_fieldname(int logic, int k)
{
const RecDes& rd = prefix().get_recdes(logic);
CHECKD(k > 0 && k <= rd.NKeys, "Invalid key on file ", logic);
const KeyDes& ky = rd.Ky[k-1];
const int idx = (logic == LF_TAB || logic == LF_TABCOM) ? 1 : 0;
const int pos = ky.FieldSeq[idx] % MaxFields;
return rd.Fd[pos].Name;
}
void append_select_clause(ostream& out, int level, const TArray& key1)
{
const TFieldref& key = (const TFieldref&)key1[level-1];
TString str;
str << " SE STR(";
if (level > 1)
str << "(NUM(LEN(" << key.name() << "))>" << key.from() << ')'; // SE LEN(CODCONTO)>=4
if (level < key1.items())
{
if (level > 1) str << "&&";
str << "(NUM(LEN(" << key.name() << "))<=" << key.to() << ')'; // SE LEN(CODCONTO)<=7
}
str << ')';
out << str << endl;
}
void append_run_clause(ostream& out, int logicnum)
{
const TRectype r(logicnum);
TString app; r.get_relapp(app);
if (app.not_empty())
out << "AD RU " << app << endl;
}
void create_browse1(TEdit_field& kfld, int level, TConfig& cfg,
int logic,
const char* key_var, short key_id,
const char* des_var, short des_id,
const TArray& key1, const TArray& key2)
{
TFilename tmp; tmp.temp();
ofstream out(tmp);
out << "US " << logic << endl;
append_select_clause(out, level, key1);
append_run_clause(out, logic);
for (int i = 1; i <= level; i++)
{
const TString& picture = cfg.get(key_var, NULL, i);
const TString& prompt = cfg.get(des_var, NULL, i);
const TFieldref& field = (const TFieldref&)key1[i-1];
const int length = field.to() - field.from();
out << "IN " << field << ' ' << (key_id+i-1) << endl;
out << "DI \"" << prompt;
if (length > prompt.len())
out << '@' << length;
out << "\" " << field << endl;
out << "OU " << (key_id+i-1) << ' ' << field << endl;
out << "FI " << field << endl;
}
const TFieldref& field = (const TFieldref&)key2[0];
out << "DI \"Descrizione@50\" " << field << endl;
out << "OU " << (des_id+level-1) << ' ' << field << endl;
out << "CH RE" << endl;
out << "EN" << endl;
out.close();
TScanner scan(tmp);
while (scan.pop() != "EN")
kfld.parse_item(scan);
xvt_fsys_removefile(tmp);
}
void create_browse2(TEdit_field& kfld, int level, TConfig& cfg,
int logic,
const char* key_var, short key_id,
const char* des_var, short des_id,
const TArray& key1, const TArray& key2)
{
const TFieldref& field = (const TFieldref&)key2[0];
TString str2; str2 << field;
TFilename tmp; tmp.temp();
ofstream out(tmp);
out << "US " << logic << " KE 2";
append_select_clause(out, level, key1);
append_run_clause(out, logic);
out << "DI \"Descrizione@50\" " << str2 << endl;
out << "IN " << str2 << ' ' << kfld.dlg() << endl;
out << "OU " << kfld.dlg() << ' ' << str2 << endl;
int from = 1, to = 1;
for (int i = 1; i <= level; i++)
{
const TString& picture = cfg.get(key_var, NULL, i);
const TString& prompt = cfg.get(des_var, NULL, i);
const TFieldref& field = (const TFieldref&)key1[i-1];
const int length = field.to() - field.from();
out << "DI \"" << prompt;
if (length > prompt.len())
out << '@' << length;
out << "\" " << field << endl;
out << "OU " << (key_id+i-1) << ' ' << field << endl;
from = to+1;
}
out << "CH NO" << endl;
out << "EN" << endl;
out.close();
TScanner scan(tmp);
while (scan.pop() != "EN")
kfld.parse_item(scan);
xvt_fsys_removefile(tmp);
}
int create_fields(TMask& msk, int logicnum, int x, int y,
const char* key_var, short key_id,
const char* des_var, short des_id)
{
TConfig cfg(CONFIG_DITTA, "ca");
TArray key1, key2;
int maxkeylen = 0, maxdeslen = 0;
int level;
int from = 1, to = 1;
for (level = 1; ; level++)
{
const TString& prompt = cfg.get(des_var, NULL, level);
if (prompt.blank())
break;
const TString& picture = cfg.get(key_var, NULL, level);
const int keylen = picture.len();
const int deslen = prompt.len();
if (keylen > maxkeylen) maxkeylen = keylen;
if (deslen > maxdeslen) maxdeslen = deslen;
to = from+keylen-1;
TString80 str; str = get_key_fieldname(logicnum, 1);
str << '[' << from << ',' << to << ']';
key1.add(new TFieldref(str, logicnum));
from = to+1;
}
key2.add(new TFieldref(get_key_fieldname(logicnum, 2), logicnum));
maxdeslen++;
const int tab0 = x;
const int tab1 = tab0 + maxdeslen + maxkeylen + 4;
for (int i = 1; i < level; i++)
{
const short kid = key_id+i-1;
const TString& picture = cfg.get(key_var, NULL, i);
TString80 prompt = cfg.get(des_var, NULL, i);
prompt.left_just(maxdeslen);
TEdit_field& kfld = msk.add_string(kid, 0, prompt, tab0, y+i-1, picture.len(), "BU");
create_browse1(kfld, i, cfg, logicnum, key_var, key_id, des_var, des_id, key1, key2);
kfld.set_group(2);
const short did = des_id+i-1;
TEdit_field& dfld = msk.add_string(did, 0, "", tab1, y+i-1, 50, "B", 72+tab0-tab1);
create_browse2(dfld, i, cfg, logicnum, key_var, key_id, des_var, des_id, key1, key2);
dfld.set_group(2);
}
return level;
}
///////////////////////////////////////////////////////////
// TRiparti_msk
///////////////////////////////////////////////////////////
class TRiparti_msk : public TAutomask
{
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
void create_sheet();
public:
TRiparti_msk();
};
bool TRiparti_msk::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
{
case F_TIPORIP:
if (e == fe_init || e == fe_modify)
{
TSheet_field& sf = sfield(F_SHEET);
TMask& sm = sf.sheet_mask();
const int t = atoi(o.get());
sm.show(101, t == 0); // Percentuale
sm.show(201, t == 2); // Parti
}
if (e == fe_close && atoi(o.get()) == 0)
{
TSheet_field& sf = sfield(F_SHEET);
real tot;
FOR_EACH_SHEET_ROW(sf, i, row)
tot += real(row->get(0));
tot.round(2);
if (tot != CENTO)
return error_box(TR("Il totale delle percentuali di riparto deve essere 100"));
}
break;
default:
break;
}
return true;
}
void TRiparti_msk::create_sheet()
{
TSheet_field& sf = sfield(F_SHEET);
TMask& sm = sf.sheet_mask();
sm.hide(-1);
TConfig ini(CONFIG_DITTA, "ca");
const bool use_pdc = ini.get_bool("UsePdcc");
create_fields(sm, LF_CDC, 1, 1, "CdC", 202, "CdCDes", 252);
create_fields(sm, LF_COMMESSE, 1, 5, "Cms", 206, "CmsDes", 256);
create_fields(sm, LF_CDC, 1, 9, "CdC", 210, "CdCDes", 260);
if (!use_pdc)
{
create_fields(sm, LF_PCONANA,1, 13, "Pdci", 214, "PdciDes", 264);
sm.hide(-6);
}
for (short id = 217; id >= 202; id--)
{
short dlg = id;
if (use_pdc && id >= 213)
dlg -= 100;
const int pos = sm.id2pos(dlg);
if (pos >= 0)
{
TMask_field& f = sm.fld(pos);
const int size = f.size();
const TString& prompt = f.prompt();
sf.set_column_header(id, prompt);
sf.set_column_width(id, (2+max(size, prompt.len())) * CHARX);
}
else
sf.delete_column(id);
}
}
TRiparti_msk::TRiparti_msk() : TAutomask("ca0800a")
{
create_fields(*this, LF_CDC, 2, 5, "CdC", F_CODCDC_1, "CdCDes", F_DESCDC_1);
create_fields(*this, LF_COMMESSE, 2, 11, "Cms", F_CODCMS_1, "CmsDes", F_DESCMS_1);
create_sheet();
}
///////////////////////////////////////////////////////////
// TRiparti_app
///////////////////////////////////////////////////////////
class TRiparti_app : public TRelation_application
{
TRelation* _rel;
TRiparti_msk* _msk;
const TString& somma_campi(TToken_string& row, int first) const;
void write_rows();
void spezza_campo(const TString& str, TToken_string& row, int first) const;
void read_rows();
protected:
virtual bool user_create();
virtual bool user_destroy();
virtual int write(const TMask& m);
virtual int rewrite(const TMask& m);
virtual TRelation* get_relation() const { return _rel; }
virtual TMask* get_mask(int) { return _msk; }
};
const TString& TRiparti_app::somma_campi(TToken_string& row, int first) const
{
TSheet_field& sheet = _msk->sfield(F_SHEET);
TMask& m = sheet.sheet_mask();
short id = 200 + first;
if (m.id2pos(id) < 0)
id -= 100;
TString& str = get_tmp_string(20);
for (int i = first; i < first+4; i++)
{
TString80 token = row.get(i);
if (m.id2pos(id+i) < 0)
break;
const TEdit_field& fld = m.efield(id+1);
token.left_just(fld.size());
str << token;
}
return str;
}
void TRiparti_app::spezza_campo(const TString& str, TToken_string& row, int first) const
{
TSheet_field& sheet = _msk->sfield(F_SHEET);
TMask& m = sheet.sheet_mask();
short id = 200 + first;
if (m.id2pos(id) < 0)
id -= 100;
int start = 0;
for (int i = first; i < first+4; i++)
{
if (m.id2pos(id+i) < 0)
break;
const TEdit_field& fld = m.efield(id+1);
const int len = fld.size();
const TString& token = str.mid(start, len);
row.add(token, i);
start += len;
}
}
void TRiparti_app::write_rows()
{
TRectype* key = new TRectype(LF_RRIP);
const char tipo = _msk->get(F_TIPO)[0];
key->put("TIPO", tipo);
key->put("CODICE", _msk->get(tipo == 'B' ? F_CODICE_B : F_CODICE_I));
TRecord_array a(LF_RRIP, "NRIGA");
a.set_key(key);
TSheet_field& sheet = _msk->sfield(F_SHEET);
FOR_EACH_SHEET_ROW(sheet, i, row)
{
TRectype& rec = a.row(i+1, true); // Crea una riga nuova
rec.put("RIPARTO", row->get(0));
rec.put("CODCOSTO", somma_campi(*row, 1));
rec.put("CODCMS", somma_campi(*row, 5));
rec.put("CODFASE", somma_campi(*row, 9));
rec.put("CODCONTO", somma_campi(*row,13));
}
a.rewrite();
}
void TRiparti_app::read_rows()
{
TRectype key (LF_RRIP);
const char tipo = _msk->get(F_TIPO)[0];
key.put("TIPO", tipo);
key.put("CODICE", _msk->get(tipo == 'B' ? F_CODICE_B : F_CODICE_I));
TRecord_array a(key, "NRIGA");
TSheet_field& sheet = _msk->sfield(F_SHEET);
sheet.destroy();
for (int i = 1; i <= a.rows(); i++)
{
const TRectype& rec = a.row(i);
TToken_string& row = sheet.row(i-1);
row = rec.get("RIPARTO");
spezza_campo(rec.get("CODCOSTO"), row, 1);
spezza_campo(rec.get("CODCMS"), row, 5);
spezza_campo(rec.get("CODFASE"), row, 9);
spezza_campo(rec.get("CODCONTO"), row,13);
}
}
int TRiparti_app::write(const TMask& m)
{
const int err = TRelation_application::write(m);
if (err == NOERR)
write_rows();
return err;
}
int TRiparti_app::rewrite(const TMask& m)
{
const int err = TRelation_application::rewrite(m);
if (err == NOERR)
write_rows();
return err;
}
bool TRiparti_app::user_create()
{
_rel = new TRelation(LF_RIP);
_msk = new TRiparti_msk;
return true;
}
bool TRiparti_app::user_destroy()
{
delete _rel;
delete _msk;
return true;
}
int ca0800(int argc, char* argv[])
{
TRiparti_app a;
a.run(argc, argv, TR("Tabella di ripartizione"));
return 0;
}