Patch level : 10.0 286

Files correlati     : pe0.exe
Ricompilazione Demo : [ ]
Commento            :

Preventivi/incarichi (Dinamica)


git-svn-id: svn://10.65.10.50/trunk@18732 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
alex 2009-04-17 16:14:22 +00:00
parent 6da5458f1f
commit 5ea42a63e5
10 changed files with 1577 additions and 0 deletions

16
pe/pe0.cpp Executable file
View File

@ -0,0 +1,16 @@
#include <xvt.h>
#include "pe0.h"
int main(int argc, char** argv)
{
const int r = (argc > 1) ? argv[1][1] - '0' : 0;
switch (r)
{
case 3: pe0400(argc, argv); break; // gestione preventivi
case 4: pe0500(argc, argv); break; // generazione ordini e preventivi esecutivi
case 5: pe0500(argc, argv); break; // generazione ordini di produzione e fabbisogni
default: pe0400(argc, argv); break; // gestione preventivi
}
return 0;
}

8
pe/pe0.h Executable file
View File

@ -0,0 +1,8 @@
#ifndef __LV3_H
#define __LV3_H
int pe0400(int argc, char* argv[]);
int pe0500(int argc, char* argv[]);
int pe0600(int argc, char* argv[]);
#endif // __LV3_H

479
pe/pe0400.cpp Executable file
View File

@ -0,0 +1,479 @@
#include <colors.h>
#include "../ve/ve0100.h"
#include "../ve/veini.h"
#include "../ve/veuml.h"
#include "../ve/veuml3.h"
#include "../ve/verig.h"
#include "../ve/vepriv.h"
#include "../ve/velib.h"
#include "../ve/velib04.h"
#define F_K F_USERFLD
#define F_DETTAGLIO F_USERFLD+1
#define FOR_EACH_DOC_ROW_BACK(d, r, row) const TRiga_documento* row = NULL; for (int r = d.rows(); r > 0 && (row = &d[r]) != NULL; r--)
//////////////////////////////////////////
//// CLASSE TGestione_preventivo_msk ////
//////////////////////////////////////////
//Definizione della classe della maschera
class TGestione_preventivo_msk : public TDocumento_mask
{
int _rule;
protected:
//hanlder di documento:
static bool pe_data_handler(TMask_field& f, KEY k);
//handler di riga:
static bool pe_ritirato_handler(TMask_field& f, KEY k);
static bool pe_codart_handler(TMask_field& f, KEY k);
static bool pe_umart_handler(TMask_field& f, KEY k);
static bool ss_notify(TSheet_field& ss, int r, KEY key);
virtual void on_idle();
virtual void highlight_row(int row, bool dirty = true, bool update = true);
public:
virtual void user_set_handler( short fieldid, int index);
virtual void user_set_row_handler(TMask& rm, short field, int index);
virtual TVariable_mask * riga_mask(int numriga);
virtual void doc2mask(bool reload_clifo = true, bool update = true);
TGestione_preventivo_msk(const char* tipodoc);
};
//////////////////////////////////////////
//// CLASSE TGestione_preventivo_APP ////
//////////////////////////////////////////
// Definizione della classe dell'applicazione motore
class TGestione_preventivo_app : public TMotore_application
{
protected:
virtual TMask* get_mask( int mode );
virtual int write( const TMask& m );
virtual int rewrite( const TMask& m );
virtual int read ( TMask& m );
virtual void init_insert_mode( TMask& m );
void elimina_vuote( const TMask& m);
public:
TGestione_preventivo_app() {}
};
inline TGestione_preventivo_app& peapp() { return (TGestione_preventivo_app &)main_app(); };
//////////////////////////////////////////
//// CLASSE TGestione_preventivo_MSK ////
//////////////////////////////////////////
////////////////////////////
// HANDLER DI DOCUMENTO //
////////////////////////////
void TGestione_preventivo_msk:: on_idle()
{
TDocumento_mask::on_idle();
}
//magico metodo per settare, al cambio riga dello sheet, il focus sul campo desiderato (il campo in questione è..
//..definito nella on_idle(); ricordarsi la set_notify() nel costruttore della maschera senno' viene eseguito l'ss_notify()..
//..standard e non questo qui ridefinito. Allah!
bool TGestione_preventivo_msk::ss_notify(TSheet_field& ss, int r, KEY key)
{
TGestione_preventivo_msk& dmsk = (TGestione_preventivo_msk&) ss.mask();
TSheet_field & sh = dmsk.sfield(F_SHEET);
TDocumento& doc = dmsk.doc();
TRiga_documento& row = doc[r + 1];
switch (key)
{
case K_ENTER: // modifica
{
TMask & m = sh.sheet_row_mask(r);
const int level = row.get_int(RDOC_LEVEL);
const bool prodfin = level == 0;
const bool price_enabled = (r + 1 == doc.physical_rows()) || (level < doc[r + 2].get_int(RDOC_LEVEL));
short id;
m.enable(FR_PREZZO, price_enabled);
m.enable(FR_JOLLY2, price_enabled);
for (id = F_CDC1; id < F_CDC12; id++)
m.enable(id, prodfin);
for (id = F_DESCDC1; id < F_DESCDC12; id++)
m.enable(id, prodfin);
}
break;
case K_INS: // Inserimento
{
const int new_sheet_r = doc.physical_rows() == 0 ? 0 : r + 1;
const int new_r = new_sheet_r + 1;
int level = 0;
doc.insert_row(new_r, dmsk.get( F_LBTIPORIGA ));
TRiga_documento & new_row = doc[new_r];
if (r > 0 && row.is_merce())
{
level = row.get_int(RDOC_LEVEL);
if (dmsk.get_bool(F_DETTAGLIO))
{
level++;
dmsk.reset(F_DETTAGLIO);
}
if (level > 0)
{
new_row.put(RDOC_CODCOSTO, row.get(RDOC_CODCOSTO));
new_row.put(RDOC_CODCMS, row.get(RDOC_CODCMS));
new_row.put(RDOC_FASCMS, row.get(RDOC_FASCMS));
short id;
sh.disable_cell(r, sh.cid2index(FR_PREZZO));
sh.disable_cell(r, sh.cid2index(FR_JOLLY2));
row.zero(RDOC_PREZZO);
row.zero(RDOC_K);
row.autoload(sh);
for (id = F_CDC1; id < F_CDC12; id++)
sh.disable_cell(new_sheet_r, sh.cid2index(id));
}
}
new_row.put(RDOC_LEVEL, level);
TString tree;
if (level > 0)
tree.fill(' ');
tree << '+';
tree.rpad(10, '-');
row.put(RDOC_TREE, tree);
}
break;
default:
break;
}
return TDocumento_mask::ss_notify(ss, r, key);
}
void TGestione_preventivo_msk::highlight_row(int row, bool dirty, bool update)
{
TRiga_documento& rigadoc = doc()[row + 1];
TSheet_field& sf = sfield(F_SHEET);
COLOR back1 = NORMAL_BACK_COLOR, back2 = FOCUS_BACK_COLOR;
const TColor_rule * c = (TColor_rule *) color_rules().objptr(_rule);
if (c != NULL)
{
COLOR fore;
c->colors(back2, fore);
}
const COLOR back = blend_colors(back1, back2, ((double) rigadoc.get_int(RDOC_LEVEL)) / 10.0);
sf.set_back_and_fore_color(back, COLOR_INVALID, row);
TDocumento_mask::highlight_row(row, dirty, update);
}
TVariable_mask * TGestione_preventivo_msk::riga_mask(int numriga)
{
TVariable_mask* m = TDocumento_mask::riga_mask(numriga);
if ( m != NULL)
{
const TRiga_documento& riga = doc()[numriga + 1];
TEdit_field & tree = m->add_string(FR_JOLLY1, 0, "", 30, 50, 10, "D");
TEdit_field & k = m->add_string(FR_JOLLY2, 0, "K ", 2, 20, 25);
tree.set_field(RDOC_TREE);
k.set_field(RDOC_K);
}
return m;
}
void TGestione_preventivo_msk::doc2mask(bool reload_clifo, bool update)
{
TDocumento_mask::doc2mask(reload_clifo, false);
TSheet_field& s = sfield(F_SHEET);
const int righe = s.items();
const TDocumento & d = doc();
for (int i = 0; i < righe; i++)
{
const TRiga_documento & row = d[i + 1];
const int level = row.get_int(RDOC_LEVEL);
const bool prodfin = level == 0;
const bool price_enabled = (i + 1 == d.physical_rows()) || (level < d[i + 2].get_int(RDOC_LEVEL));
s.enable_cell(i, s.cid2index(FR_PREZZO), price_enabled);
s.enable_cell(i, s.cid2index(FR_JOLLY2), price_enabled);
for (short id = F_CDC1; id < F_CDC12; id++)
s.enable_cell(i, s.cid2index(id), prodfin);
}
//aggiorna i colori delle righe e forza l'update dello sheet
highlight();
}
//PE_TESTATA_HANDLER: handler che si occupa di decodificare i campi data in testata
bool TGestione_preventivo_msk::pe_data_handler(TMask_field& f, KEY k)
{
bool ok = true;
TGestione_preventivo_msk& dmsk = (TGestione_preventivo_msk&)f.mask();
return ok;
}
///////////////////////
// HANDLER DI RIGA //
///////////////////////
//PE_RITIRATO_HANDLER: handler sul campo ritirato, che copia nel campo consegnato
//lo stesso valore eventualmente arrotondato e aggiorna il campo "dotazione odierna" (sempre)
//e il campo "dotazione temporanea" (se la causale è giusta)
bool TGestione_preventivo_msk::pe_ritirato_handler(TMask_field& f, KEY k)
{
if (f.to_check(k))
{
TMask& msk = f.mask();
}
return true;
}
bool TGestione_preventivo_msk::pe_codart_handler(TMask_field& f, KEY k)
{
bool ok = codart_handler( f, k );
if (ok && (k == K_ENTER || k == K_TAB))
{
TMask& row_mask = f.mask();
if (row_mask.field(FR_JOLLY2).active())
{
TSheet_field * sh = row_mask.get_sheet();
if (sh != NULL)
{
TDocumento_mask & mask = (TDocumento_mask &) sh->mask();
TDocumento & doc = mask.doc();
if (f.to_check(k, true))
{
const int r = sh->selected();
const TString& codart = mask.get(FR_CODARTMAG);
TRiga_documento & row = doc[r + 1];
if (codart.full())
{
const TArticolo_giacenza & art = cached_article(codart);
TString80 k = art.get(ANAMAG_PERCRIC);
if (k.blank())
{
const TString catmer = art.get(ANAMAG_GRMERC);
k = cache().get("GMC", catmer, "S2");
if (k.blank())
k = cache().get("GMC", catmer.left(3), "S2");
}
}
}
}
}
}
return ok;
}
bool TGestione_preventivo_msk::pe_umart_handler(TMask_field& f, KEY k)
{
bool ok = umart_handler( f, k );
if (ok)
{
TMask& row_mask = f.mask();
TSheet_field * sh = row_mask.get_sheet();
if (sh != NULL)
{
TDocumento_mask & mask = (TDocumento_mask &) sh->mask();
TDocumento & doc = mask.doc();
if (k == K_F8)
{
const int r = sh->selected();
if (r > 0)
{
TRiga_documento & row = doc[r + 1];
const int level = row.get_int(RDOC_LEVEL);
if (level > 0)
{
TRiga_documento & row = doc[r];
const real qta_prec = row.get_real(RDOC_QTA);
real qta(f.get());
TToken_string & shrow = sh->row(r);
qta *= qta_prec;
shrow.add(qta.string(), sh->cid2index(FR_UMQTA));
sh->force_update(r);
f.focusdirty();
}
}
}
if (f.to_check(k, true))
{
const int r = sh->selected();
TRiga_documento & row = doc[r + 1];
const real old_qta = row.get_real(RDOC_QTA);
const real qta(f.get());
const int level = row.get_int(RDOC_LEVEL);
if (old_qta != qta)
{
const int rows = doc.physical_rows();
for (int i = r + 2; level < doc[i].get_int(RDOC_LEVEL) && i <= rows; i++)
{
TToken_string & shrow = sh->row(i - 1);
real row_qta(shrow.get(sh->cid2index(FR_UMQTA)));
row_qta *= qta;
row_qta /= old_qta;
shrow.add(row_qta.string(), sh->cid2index(FR_UMQTA));
doc[i].put(RDOC_QTA, row_qta);
}
sh->force_update();
}
}
}
}
return ok;
}
//metodo che setta gli handler sui campi di riga
void TGestione_preventivo_msk::user_set_row_handler(TMask& rm, short field, int index)
{
switch(index)
{
case 5101: rm.set_handler(field, pe_ritirato_handler); break;
case 5102: rm.set_handler(field, pe_codart_handler); break;
default : TDocumento_mask::user_set_row_handler(rm, field, index); break;
}
}
//metodo che setta l'handler di bolla
void TGestione_preventivo_msk::user_set_handler( short fieldid, int index)
{
switch(index)
{
case 5101: set_field_handler(fieldid, pe_data_handler); break;
default : TDocumento_mask::user_set_handler(fieldid, index); break;
}
}
TGestione_preventivo_msk::TGestione_preventivo_msk(const char* tipodoc) : TDocumento_mask(tipodoc)
{
TConfig* configpe = new TConfig(CONFIG_DITTA, "pe");
sfield(F_SHEET).set_auto_append();
sfield(F_SHEET).set_notify( ss_notify );
_rule = color_rules().add(new TColor_rule("Livello", "", _numexpr, FOCUS_BACK_COLOR, FOCUS_COLOR));
}
//////////////////////////////////////////
//// CLASSE TGESTIONE_PREVENTIVO_APP ////
//////////////////////////////////////////
//ridefinisco il metodo get_mask delle TMotore_application
TMask* TGestione_preventivo_app::get_mask( int mode )
{
if (mode == MODE_INS || mode == MODE_MOD)
{
TString4 tipodoc;
if (mode == MODE_MOD)
tipodoc = get_relation()->curr().get(DOC_TIPODOC); // Lo prendo dalla relazione (Gelai)
else
tipodoc = TMotore_application::get_mask(MODE_QUERY)->get(F_TIPODOC);
if (_doc_masks.objptr(tipodoc) == NULL)
{
TGestione_preventivo_msk* m = new TGestione_preventivo_msk(tipodoc);
_doc_masks.add(tipodoc, m);
const TTipo_documento& tdoc = m->doc().tipo();
const TString_array& handlers = tdoc.handlers();
FOR_EACH_ARRAY_ROW(handlers, i, row)
{
m->user_set_handler( row->get_int( 0 ), row->get_int( 1 ) );
}
TSheet_field & sh = m->sfield(F_SHEET);
const int y = sh.y_pos() - 1;
TEdit_field & k = m->add_string(F_K, sh.page(), "K ", 2, y, 10, "D");
k.set_field(DOC_K);
m->add_boolean(F_DETTAGLIO, sh.page(), "Dettaglia ", 30, y);
}
}
return TMotore_application::get_mask(mode);
}
//ridefinisco il metodo write delle TMotore_application
int TGestione_preventivo_app::write( const TMask& m )
{
TDocumento& doc = ((TDocumento_mask&) m).doc();
const TString k = doc.get(DOC_K);
for (int i = 1 ; i <= doc.physical_rows(); i++)
if (doc[i].get(RDOC_K).blank())
doc[i].put(RDOC_K, k);
return TMotore_application::write(m);
}
//ridefinisco il metodo rewrite delle TMotore_application
int TGestione_preventivo_app::rewrite( const TMask& m )
{
TDocumento& doc = ((TDocumento_mask&) m).doc();
const TString k = doc.get(DOC_K);
for (int i = 1 ; i <= doc.physical_rows(); i++)
if (doc[i].get(RDOC_K).blank())
doc[i].put(RDOC_K, k);
return TMotore_application::rewrite(m);
}
//ridefinisco il metodo read della TMotore_application
int TGestione_preventivo_app::read(TMask& m)
{
const int err = TMotore_application::read(m);
if (err == NOERR)
{
TDocumento_mask& mask = (TDocumento_mask&) m;
TDocumento& doc = mask.doc();
const TString k = doc.get(DOC_K);
for (int i = 1 ; i <= doc.physical_rows(); i++)
if (k == doc[i].get(RDOC_K))
doc[i].zero(RDOC_K);
}
return err;
}
//ridefinisco il metodo init_insert_mode della TMotore_application
void TGestione_preventivo_app::init_insert_mode(TMask &m)
{
TGestione_preventivo_msk & mask = (TGestione_preventivo_msk&) m;
TDocumento& d = mask.doc();
return TMotore_application::init_insert_mode(m);
}
int pe0400( int argc, char* argv[])
{
TGestione_preventivo_app a;
a.run( argc, argv, TR("Gestione Preventivi"));
return 0;
}

292
pe/pe0500.cpp Executable file
View File

@ -0,0 +1,292 @@
#include <applicat.h>
#include <automask.h>
#include <progind.h>
#include <relation.h>
#include <utility.h>
#include "pe0500.h"
#include "../ve/velib.h"
#include "../ve/velib04.h"
///////////////////////////////////////////////////////////
// TGenerazione_esecutivo
///////////////////////////////////////////////////////////
class TGenerazione_esecutivo : public TCopia_documento
{
protected:
virtual void post_process_output(TLista_documenti& doc_out);
void genera_matricola(TRiga_documento & row);
public:
TGenerazione_esecutivo(const char* cod) : TCopia_documento(cod) {}
virtual ~TGenerazione_esecutivo() { }
};
void TGenerazione_esecutivo::genera_matricola(TRiga_documento & row)
{
for (int livello = 0; livello < 4; livello++)
{
TToken_string * str = row.tipo().genconf(livello);
if (str != NULL)
{
const TString codart = row.get(RDOC_CODART);
if (codart.full())
{
TString code;
const TRectype & anamag = cache().get(LF_ANAMAG, codart);
const int items = str->items();
for (int i = 0; i < items; i++)
{
const TString & name = str->get(i);
if (name.starts_with("PROG"))
{
TTable lv(format("LV%1d", livello + 1));
const int chars = atoi(name.after("PROG"));
lv.put("CODTAB", code);
if (lv.read(_isequal) != NOERR)
{
lv.zero();
lv.put("CODTAB", code);
lv.write();
}
const int prog = lv.get_int("I0") + 1;
lv.put("I0", prog);
lv.rewrite();
TString s; s << prog; s.lpad(chars, '0');
code << s;
}
else
if (name.starts_with("33."))
{
TFieldref fld(name.after("33."), LF_DOC);
code << fld.read(row.doc());
}
else
if (name.starts_with("34."))
{
TFieldref fld(name.after("34."), LF_RIGHEDOC);
code << fld.read(row);
}
else
if (name.starts_with("47."))
{
TFieldref fld(name.after("47."), LF_ANAMAG);
code << fld.read(anamag);
}
}
row.put(RDOC_LIVELLO, code);
}
}
}
}
void TGenerazione_esecutivo::post_process_output(TLista_documenti& doc_out)
{
const int items = doc_out.items();
for (int d = 0; d < items; d++)
{
const TDocumento& doc = doc_out[d];
const int rows = doc.physical_rows();
for (int r = 1; r <= rows; r++)
{
TRiga_documento & row = (TRiga_documento &)doc[r];
if (row.get_int(RDOC_LEVEL) == 0)
genera_matricola(row);
}
}
}
///////////////////////////////////////////////////////////
// TGenerazione_orsine
///////////////////////////////////////////////////////////
class TGenerazione_ordine : public TCopia_documento
{
protected:
virtual void post_process_output(TLista_documenti& doc_out);
public:
TGenerazione_ordine(const char* cod) : TCopia_documento(cod) {}
virtual ~TGenerazione_ordine() { }
};
void TGenerazione_ordine::post_process_output(TLista_documenti& doc_out)
{
const int items = doc_out.items();
for (int d = 0; d < items; d++)
{
TDocumento& doc = doc_out[d];
const int rows = doc.physical_rows();
real total;
for (int r = rows; r > 0; r--)
{
TRiga_documento & row = (TRiga_documento &)doc[r];
const int level = row.get_int(RDOC_LEVEL);
if (level != 0)
{
const TString & k = row.get(RDOC_K);
TString ge;
real perc;
real importo = row.importo(true, false);
if (scontoexpr2perc(k, false, ge, perc))
importo *= (2 - perc);
total += importo;
doc.destroy_row(r, true);
}
else
{
if (total != ZERO)
{
const real qta = row.get_real(RDOC_QTA);
const real price = total / qta;
TCurrency_documento c(price, doc, true);
row.put(RDOC_PREZZO, c.get_value());
}
total = ZERO;
}
}
}
}
///////////////////////////////////////////////////////////
// TGenEsecutivo mask
///////////////////////////////////////////////////////////
class TGenEsecutivo_mask : public TAutomask
{
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
public:
TGenEsecutivo_mask() : TAutomask("pe0500a") { open(); }
};
bool TGenEsecutivo_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
{
case F_FROM_FRNDOC:
case F_FROM_TONDOC:
if (e == fe_modify || e == fe_init)
{
const long docfr = get_long(F_FROM_FRNDOC);
const long docto = get_long(F_FROM_TONDOC);
if (docto > 0L && docfr > docto)
return error_box("Il documento finale non puo' essere maggiore di quello iniziale");
}
break;
default:
break;
}
return TRUE;
}
///////////////////////////////////////////////////////////
// Main program
///////////////////////////////////////////////////////////
class TGenEsecutivo_app : public TSkeleton_application
{
protected:
public:
virtual void main_loop();
};
void TGenEsecutivo_app::main_loop()
{
open_files(LF_TAB, LF_TABCOM, LF_DOC, LF_RIGHEDOC, LF_CONDV, LF_RCONDV,
LF_ANAMAG, LF_SCONTI, LF_UMART, LF_CLIFO, LF_CFVEN, LF_INDSP,
LF_OCCAS, LF_MOVMAG, LF_RMOVMAG, LF_SVRIEP, LF_AGENTI, LF_PERCPROV, 0);
TGenEsecutivo_mask m;
while (m.run() == K_ENTER)
{
const TDate data(m.get_date(F_DATA));
TRectype rec_from(LF_DOC);
rec_from.put(DOC_ANNO, m.get(F_FROM_ANNO));
rec_from.put(DOC_CODNUM, m.get(F_FROM_NUM));
rec_from.put(DOC_PROVV, m.get(F_FROM_PROVV));
rec_from.put(DOC_NDOC, m.get(F_FROM_FRNDOC));
TRectype rec_to(rec_from);
rec_to.put(DOC_NDOC, m.get(F_FROM_TONDOC));
// Costruisce il filtro sui tipi documento selezionati
// Il pipe significa OR per le espressioni
TRelation rel(LF_DOC);
TCursor cur(&rel, "", 1, &rec_from, &rec_to);
const long tot = cur.items();
if (tot > 0L)
{
TGenerazione_esecutivo e(m.get(F_CODICE_ESEC));
TGenerazione_ordine o(m.get(F_CODICE_ORC));
e.preserve_original_row();
o.preserve_original_row();
cur.freeze();
TProgind pi(tot, "Generazione in corso...", FALSE, TRUE);
for (cur = 0; cur.pos() < tot; ++cur)
{
pi.addstatus(1);
TDocumento srcdoc(cur.curr()), newdoc;
if (e.is_document_ok(srcdoc))
{
TLista_documenti doc_in;
TLista_documenti doc_out;
doc_in.add(srcdoc);
e.elabora(doc_in, doc_out, data);
doc_in.rewrite();
doc_out.write();
doc_in.destroy(-1);
{
const TDocumento & esecutivo = doc_out[0];
for (int r = esecutivo.physical_rows(); r > 0; r--)
{
TRiga_documento & outrow = (TRiga_documento &) esecutivo[r];
const TRiga_documento & srcrow = srcdoc[r];
outrow.set_original_rdoc_key(srcrow);
}
doc_in.add(esecutivo);
}
doc_out.destroy(-1);
o.elabora(doc_in, doc_out, data);
doc_in.rewrite();
doc_out.write();
}
}
}
else
warning_box("Nessun documento soddisfa i vincoli indicati");
}
}
int pe0500(int argc, char* argv[])
{
TGenEsecutivo_app a;
a.run(argc, argv, "Generazione Preventivi esecutivi e Ordini Clienti");
return 0;
}

12
pe/pe0500.h Executable file
View File

@ -0,0 +1,12 @@
#define F_FROM_ANNO 201
#define F_FROM_NUM 202
#define F_FROM_PROVV 203
#define F_FROM_DES 204
#define F_TIPI_DOC 205
#define F_FROM_FRNDOC 206
#define F_FROM_TONDOC 207
#define F_CODICE_ESEC 208
#define F_DESCR_ESEC 209
#define F_CODICE_ORC 210
#define F_DESCR_ORC 211
#define F_DATA 212

145
pe/pe0500a.uml Executable file
View File

@ -0,0 +1,145 @@
#include "pe0500.h"
TOOLBAR "topbar" 0 0 0 2
#include <stdbar.h>
ENDPAGE
PAGE "Generazione preventivi esecutivi e ordini" 0 0 0 0
GROUPBOX DLG_NULL 76 5
BEGIN
PROMPT 1 0 "@bSorgente"
END
NUMBER F_FROM_ANNO 4
BEGIN
PROMPT 2 1 "Anno "
FLAGS "AU"
CHECKTYPE REQUIRED
END
LIST F_FROM_PROVV 1 12
BEGIN
PROMPT 60 1 ""
ITEM "D|Definitivi"
ITEM "P|Provvisori"
END
STRING F_FROM_NUM 4
BEGIN
PROMPT 2 2 "Numerazione "
USE %NUM
FLAGS "U"
INPUT CODTAB F_FROM_NUM
DISPLAY "Codice Num." CODTAB
DISPLAY "Descrizione@50" S0
OUTPUT F_FROM_NUM CODTAB
OUTPUT F_FROM_DES S0
CHECKTYPE REQUIRED
END
STRING F_FROM_DES 50
BEGIN
PROMPT 22 2 ""
USE %NUM KEY 2
INPUT S0 F_FROM_DES
DISPLAY "Descrizione@50" S0
DISPLAY "Codice Num." CODTAB
COPY OUTPUT F_FROM_NUM
CHECKTYPE REQUIRED
END
NUMBER F_FROM_FRNDOC 6
BEGIN
PROMPT 2 3 "Da numero "
USE LF_DOC
JOIN LF_CLIFO INTO TIPOCF==TIPOCF CODCF==CODCF
INPUT ANNO F_FROM_ANNO SELECT
INPUT CODNUM F_FROM_NUM SELECT
INPUT PROVV F_FROM_PROVV SELECT
INPUT NDOC F_FROM_FRNDOC
DISPLAY "Num." CODNUM
DISPLAY "Anno" ANNO
DISPLAY "Provv" PROVV
DISPLAY "Tipo" TIPODOC
DISPLAY "Numero@7" NDOC
DISPLAY "Data@10" DATADOC
DISPLAY "C/F" TIPOCF
DISPLAY "Codice" CODCF
DISPLAY "Ragione Sociale@50" LF_CLIFO->RAGSOC
OUTPUT F_FROM_FRNDOC NDOC
END
NUMBER F_FROM_TONDOC 6
BEGIN
PROMPT 26 3 "A numero "
COPY USE F_FROM_FRNDOC
INPUT ANNO F_FROM_ANNO SELECT
INPUT CODNUM F_FROM_NUM SELECT
INPUT PROVV F_FROM_PROVV SELECT
INPUT NDOC F_FROM_TONDOC
COPY DISPLAY F_FROM_FRNDOC
OUTPUT F_FROM_TONDOC NDOC
END
GROUPBOX DLG_NULL 76 4
BEGIN
PROMPT 1 5 "@bDestinazione"
END
STRING F_CODICE_ESEC 8
BEGIN
PROMPT 1 6 "Esecutivi "
FLAG "U"
USE %ELD SELECT I0==4
INPUT CODTAB F_CODICE_ESEC
DISPLAY "Codice" CODTAB
DISPLAY "Descrizione@55" S0
OUTPUT F_CODICE_ESEC CODTAB
OUTPUT F_DESC_ESEC S0
CHECKTYPE REQUIRED
WARNING "E' necessario specificare il codice elaborazione"
END
STRING F_DESC_ESEC 50
BEGIN
PROMPT 20 6 ""
USE %ELD KEY 2 SELECT I0==4
INPUT S0 F_DESC_ESEC
DISPLAY "Descrizione@55" S0
DISPLAY "Codice" CODTAB
COPY OUTPUT F_CODICE_ESEC
END
STRING F_CODICE_ORC 8
BEGIN
PROMPT 1 7 "Ordini "
FLAG "U"
USE %ELD SELECT I0==4
INPUT CODTAB F_CODICE_ORC
DISPLAY "Codice" CODTAB
DISPLAY "Descrizione@55" S0
OUTPUT F_CODICE_ORC CODTAB
OUTPUT F_DESC_ORC S0
CHECKTYPE REQUIRED
WARNING "E' necessario specificare il codice elaborazione"
END
STRING F_DESC_ORC 50
BEGIN
PROMPT 20 7 ""
USE %ELD KEY 2 SELECT I0==4
INPUT S0 F_DESC_ORC
DISPLAY "Descrizione@55" S0
DISPLAY "Codice" CODTAB
COPY OUTPUT F_CODICE_ORC
END
DATE F_DATA
BEGIN
PROMPT 1 9 "Data "
END
ENDPAGE
ENDMASK

208
pe/pe0600.cpp Executable file
View File

@ -0,0 +1,208 @@
#include <applicat.h>
#include <automask.h>
#include <progind.h>
#include <relation.h>
#include <utility.h>
#include "pe0600.h"
#include "../ve/velib.h"
#include "../ve/velib04.h"
///////////////////////////////////////////////////////////
// TGenerazione_ordine_produzione
///////////////////////////////////////////////////////////
class TGenerazione_ordine_produzione : public TCopia_documento
{
protected:
virtual void post_process_output(TLista_documenti& doc_out);
public:
TGenerazione_ordine_produzione(const char* cod) : TCopia_documento(cod) {}
virtual ~TGenerazione_ordine_produzione() { }
};
void TGenerazione_ordine_produzione::post_process_output(TLista_documenti& doc_out)
{
const int items = doc_out.items();
for (int d = 0; d < items; d++)
{
TDocumento& doc = doc_out[d];
const int rows = doc.physical_rows();
int max_level = 0;
for (int r = 1; r <= rows; r++)
{
TRiga_documento & row = (TRiga_documento &)doc[r];
const int level = row.get_int(RDOC_LEVEL);
if (max_level < level)
max_level = level;
}
for (int r = rows; r >= 1; r--)
{
TRiga_documento & row = (TRiga_documento &)doc[r];
if (!row.is_merce() || row.get_int(RDOC_LEVEL) == max_level)
doc.destroy_row(r, true);
}
}
}
///////////////////////////////////////////////////////////
// TGenerazione_ordine_acquisto
///////////////////////////////////////////////////////////
class TGenerazione_ordine_acquisto : public TCopia_documento
{
protected:
virtual void post_process_output(TLista_documenti& doc_out);
public:
TGenerazione_ordine_acquisto(const char* cod) : TCopia_documento(cod) {}
virtual ~TGenerazione_ordine_acquisto() { }
};
void TGenerazione_ordine_acquisto::post_process_output(TLista_documenti& doc_out)
{
const int items = doc_out.items();
for (int d = 0; d < items; d++)
{
TDocumento& doc = doc_out[d];
const int rows = doc.physical_rows();
int max_level = -883;
for (int r = 1; r <= rows; r++)
{
TRiga_documento & row = (TRiga_documento &)doc[r];
const int level = row.get_int("LEVEL");
if (max_level < level)
max_level = level;
}
for (int r = rows; r >= 1; r--)
{
TRiga_documento & row = (TRiga_documento &)doc[r];
if (!row.is_merce() || row.get_int(RDOC_LEVEL) < max_level)
doc.destroy_row(r, true);
}
}
}
///////////////////////////////////////////////////////////
// TGenOrdini_mask
///////////////////////////////////////////////////////////
class TGenOrdini_mask : public TAutomask
{
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
public:
TGenOrdini_mask() : TAutomask("pe0600a") { open(); }
};
bool TGenOrdini_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
{
case F_FROM_FRNDOC:
case F_FROM_TONDOC:
if (e == fe_modify || e == fe_init)
{
const long docfr = get_long(F_FROM_FRNDOC);
const long docto = get_long(F_FROM_TONDOC);
if (docto > 0L && docfr > docto)
return error_box("Il documento finale non puo' essere maggiore di quello iniziale");
}
break;
default:
break;
}
return TRUE;
}
///////////////////////////////////////////////////////////
// Main program
///////////////////////////////////////////////////////////
class TGenOrdini_app : public TSkeleton_application
{
protected:
public:
virtual void main_loop();
};
void TGenOrdini_app::main_loop()
{
open_files(LF_TAB, LF_TABCOM, LF_DOC, LF_RIGHEDOC, LF_CONDV, LF_RCONDV,
LF_ANAMAG, LF_SCONTI, LF_UMART, LF_CLIFO, LF_CFVEN, LF_INDSP,
LF_OCCAS, LF_MOVMAG, LF_RMOVMAG, LF_SVRIEP, LF_AGENTI, LF_PERCPROV, 0);
TGenOrdini_mask m;
while (m.run() == K_ENTER)
{
const TDate data(m.get_date(F_DATA));
TRectype rec_from(LF_DOC);
rec_from.put(DOC_ANNO, m.get(F_FROM_ANNO));
rec_from.put(DOC_CODNUM, m.get(F_FROM_NUM));
rec_from.put(DOC_PROVV, m.get(F_FROM_PROVV));
rec_from.put(DOC_NDOC, m.get(F_FROM_FRNDOC));
TRectype rec_to(rec_from);
rec_to.put(DOC_NDOC, m.get(F_FROM_TONDOC));
// Costruisce il filtro sui tipi documento selezionati
// Il pipe significa OR per le espressioni
TRelation rel(LF_DOC);
TCursor cur(&rel, "", 1, &rec_from, &rec_to);
const long tot = cur.items();
if (tot > 0L)
{
TGenerazione_ordine_produzione e(m.get(F_CODICE_ORP));
TGenerazione_ordine_acquisto o(m.get(F_CODICE_ORA));
cur.freeze();
TProgind pi(tot, "Generazione in corso...", FALSE, TRUE);
for (cur = 0; cur.pos() < tot; ++cur)
{
pi.addstatus(1);
TDocumento srcdoc(cur.curr()), newdoc;
if (e.is_document_ok(srcdoc))
{
TLista_documenti doc_in;
TLista_documenti doc_out;
doc_in.add(srcdoc);
e.elabora(doc_in, doc_out, data);
doc_in.rewrite();
doc_out.write();
doc_in.destroy(-1);
doc_out.destroy(-1);
doc_in.add(srcdoc);
o.elabora(doc_in, doc_out, data);
doc_in.rewrite();
doc_out.write();
}
}
}
else
warning_box("Nessun documento soddisfa i vincoli indicati");
}
}
int pe0600(int argc, char* argv[])
{
TGenOrdini_app a;
a.run(argc, argv, "Generazione ordini di produzione e acquisto");
return 0;
}

12
pe/pe0600.h Executable file
View File

@ -0,0 +1,12 @@
#define F_FROM_ANNO 201
#define F_FROM_NUM 202
#define F_FROM_PROVV 203
#define F_FROM_DES 204
#define F_TIPI_DOC 205
#define F_FROM_FRNDOC 206
#define F_FROM_TONDOC 207
#define F_CODICE_ORP 208
#define F_DESCR_ORP 209
#define F_CODICE_ORA 210
#define F_DESCR_ORA 211
#define F_DATA 212

145
pe/pe0600a.uml Executable file
View File

@ -0,0 +1,145 @@
#include "pe0600.h"
TOOLBAR "topbar" 0 0 0 2
#include <stdbar.h>
ENDPAGE
PAGE "Generazione ordini di produzione e acquisto" 0 0 0 0
GROUPBOX DLG_NULL 76 5
BEGIN
PROMPT 1 0 "@bSorgente"
END
NUMBER F_FROM_ANNO 4
BEGIN
PROMPT 2 1 "Anno "
FLAGS "AU"
CHECKTYPE REQUIRED
END
LIST F_FROM_PROVV 1 12
BEGIN
PROMPT 60 1 ""
ITEM "D|Definitivi"
ITEM "P|Provvisori"
END
STRING F_FROM_NUM 4
BEGIN
PROMPT 2 2 "Numerazione "
USE %NUM
FLAGS "U"
INPUT CODTAB F_FROM_NUM
DISPLAY "Codice Num." CODTAB
DISPLAY "Descrizione@50" S0
OUTPUT F_FROM_NUM CODTAB
OUTPUT F_FROM_DES S0
CHECKTYPE REQUIRED
END
STRING F_FROM_DES 50
BEGIN
PROMPT 22 2 ""
USE %NUM KEY 2
INPUT S0 F_FROM_DES
DISPLAY "Descrizione@50" S0
DISPLAY "Codice Num." CODTAB
COPY OUTPUT F_FROM_NUM
CHECKTYPE REQUIRED
END
NUMBER F_FROM_FRNDOC 6
BEGIN
PROMPT 2 3 "Da numero "
USE LF_DOC
JOIN LF_CLIFO INTO TIPOCF==TIPOCF CODCF==CODCF
INPUT ANNO F_FROM_ANNO SELECT
INPUT CODNUM F_FROM_NUM SELECT
INPUT PROVV F_FROM_PROVV SELECT
INPUT NDOC F_FROM_FRNDOC
DISPLAY "Num." CODNUM
DISPLAY "Anno" ANNO
DISPLAY "Provv" PROVV
DISPLAY "Tipo" TIPODOC
DISPLAY "Numero@7" NDOC
DISPLAY "Data@10" DATADOC
DISPLAY "C/F" TIPOCF
DISPLAY "Codice" CODCF
DISPLAY "Ragione Sociale@50" LF_CLIFO->RAGSOC
OUTPUT F_FROM_FRNDOC NDOC
END
NUMBER F_FROM_TONDOC 6
BEGIN
PROMPT 26 3 "A numero "
COPY USE F_FROM_FRNDOC
INPUT ANNO F_FROM_ANNO SELECT
INPUT CODNUM F_FROM_NUM SELECT
INPUT PROVV F_FROM_PROVV SELECT
INPUT NDOC F_FROM_TONDOC
COPY DISPLAY F_FROM_FRNDOC
OUTPUT F_FROM_TONDOC NDOC
END
GROUPBOX DLG_NULL 76 4
BEGIN
PROMPT 1 5 "@bDestinazione"
END
STRING F_CODICE_ORP 8
BEGIN
PROMPT 1 6 "Ordini di prod. "
FLAG "U"
USE %ELD SELECT I0==4
INPUT CODTAB F_CODICE_ORP
DISPLAY "Codice" CODTAB
DISPLAY "Descrizione@55" S0
OUTPUT F_CODICE_ORP CODTAB
OUTPUT F_DESC_ORP S0
CHECKTYPE REQUIRED
WARNING "E' necessario specificare il codice elaborazione"
END
STRING F_DESC_ORP 50
BEGIN
PROMPT 20 6 ""
USE %ELD KEY 2 SELECT I0==4
INPUT S0 F_DESC_ORP
DISPLAY "Descrizione@55" S0
DISPLAY "Codice" CODTAB
COPY OUTPUT F_CODICE_ORP
END
STRING F_CODICE_ORA 8
BEGIN
PROMPT 1 7 "Ordini di acq. "
FLAG "U"
USE %ELD SELECT I0==4
INPUT CODTAB F_CODICE_ORA
DISPLAY "Codice" CODTAB
DISPLAY "Descrizione@55" S0
OUTPUT F_CODICE_ORA CODTAB
OUTPUT F_DESC_ORA S0
CHECKTYPE REQUIRED
WARNING "E' necessario specificare il codice elaborazione"
END
STRING F_DESC_ORA 50
BEGIN
PROMPT 20 7 ""
USE %ELD KEY 2 SELECT I0==4
INPUT S0 F_DESC_ORA
DISPLAY "Descrizione@55" S0
DISPLAY "Codice" CODTAB
COPY OUTPUT F_CODICE_ORA
END
DATE F_DATA
BEGIN
PROMPT 1 9 "Data "
END
ENDPAGE
ENDMASK

260
pe/prev.src Executable file
View File

@ -0,0 +1,260 @@
#include "veini.h"
#include "verig.h"
#include "veuml.h"
// Esempio di profilo documento : Profilo ordine cliente
[MAIN]
// Descrizione a caratteri del documento
TYPE=Ordine Cliente
// modifica
CAMPICALC=TOTMER|TOTPRE|SPESE|SPESIMB|SPESTRA|SPESINC|BOLLI|IMPONIBILI|IMPOSTE|TOTDOC|SCONTOD|SCONTOT|OMAGGI|TOTPROVV
CALCOLI=*
TOTPROVV =
// modifica
// Procedure utente da chiamare per il documento ( preprocessarle? )
NUOVO=
MODIFICA=
CANCELLA=
STAMPA=
RAGGRUPPA=
USER=
LINES_BEFORESHEET=1
// Indica se il documento è indirizzato ad un cliente o ad un fornitore
TIPOCF=C
//modulo di riferimento
MODULE=ve
Title(1)=Cliente
Title(2)=Pagamenti
Title(3)=Ind.Spedizione
Title(4)=Spedizione
Title(5)=Righe
Title(6)=Totali
[PROFILO]
// Si possono indicare, dopo il numero, PROMPT, HELP, WARNING cosi:
// 1|Prompt|Help|Warning
OCCASEDIT = S_NORMALE //100
OCFPI = S_DISABILITATO //100
COFI = S_NORMALE //100
STATOPAIV = S_NORMALE //100
PAIVA = S_NORMALE //100
GOLEM = S_NORMALE
GRRECAPITO = S_NORMALE //100
INDCF = S_DISABILITATO //100
CIVCF = S_DISABILITATO //100
LOCALITACF = S_DISABILITATO //100
CAPCF = S_DISABILITATO //100
PROVCOM = S_DISABILITATO //100
COMCF = S_DISABILITATO //100
DENCOM = S_DISABILITATO //100
STATOCF = S_DISABILITATO //100
DESSTATOCF = S_DISABILITATO //100
CODVAL1 = S_NORMALE //200
CODVAL2 = S_NORMALE //200
NOME_VAL1 = S_NORMALE //200
NOME_VAL2 = S_NORMALE //200
CONTROEURO = S_NORMALE //200
CAMBIO = S_NORMALE //200
DATA_CAMBIO1 = S_NORMALE //200
DATA_CAMBIO2 = S_NORMALE //200
CODLIN = S_NORMALE //300
DESLIN = S_NORMALE //300
CODPAG = S_OBBLIGATORIO //400
DESCODPAG = S_NORMALE //400
GRSCADENZE = S_NORMALE //500
DATAINSC = S_NORMALE //500
DATASCAD1 = S_DISABILITATO //500
DATASCAD2 = S_DISABILITATO //500
DATASCAD3 = S_DISABILITATO //500
DATASCAD4 = S_DISABILITATO //500
DATASCAD5 = S_DISABILITATO //500
CODABIA = S_OBBLIGATORIO //600
CODCABA = S_OBBLIGATORIO //600
DESBANAPP = S_NORMALE //600
IBAN = S_NORMALE //600
IBAN_STATO = S_NORMALE //600
IBAN_CHECK = S_NORMALE //600
BBAN = S_NORMALE //600
BBAN_CIN = S_NORMALE //600
BBAN_ABI = S_NORMALE //600
BBAN_CAB = S_NORMALE //600
BBAN_CONTO = S_NORMALE //600
CODABIP = S_NORMALE //700
CODCABP = S_NORMALE //700
DESBANPRE = S_NORMALE //700
CATVEN = S_NORMALE //800
DESCATVEN = S_DISABILITATO //800
CODLIST1 = S_NORMALE //800
CODLIST2 = S_NORMALE //800
DESLIST = S_DISABILITATO //800
CODCONT1 = S_NORMALE //810
CODCONT2 = S_NORMALE //810
DESCONT = S_DISABILITATO //810
CODCAMP = S_NORMALE //820
DESCAMP = S_DISABILITATO //820
SCONTOPERC = S_NORMALE //830
GRINDSPED = S_NORMALE //900
CODINDSP = S_NORMALE //900
RAGSOCSP = S_DISABILITATO //900
INDSP = S_DISABILITATO //900
CIVSP = S_DISABILITATO //900
LOCALITASP = S_DISABILITATO //900
CAPSP = S_DISABILITATO //900
COMSP = S_DISABILITATO //900
DENCOMSP = S_DISABILITATO //900
PROVCOMSP = S_DISABILITATO //900
STATOSP = S_DISABILITATO //900
DESSTATOSP = S_DISABILITATO //900
DATADOCRIF = S_NORMALE //1000
NUMDOCRIF = S_NOCHECK //1000
CODAGVIS = S_NORMALE //1110
DESAGVIS = S_NORMALE //1110
CODAG = S_NORMALE //1100
DESAG = S_NORMALE //1100
CODZON = S_NORMALE //1100
DESZON = S_NORMALE //1100
CODSPMEZZO = S_OBBLIGATORIO //1200
DESSPMEZZO = S_NORMALE //1200
CODPORTO = S_NORMALE //1210
DESPORTO = S_NORMALE //1210
CODNOTESP1 = S_NORMALE //1300
DESNOTESP1 = S_NORMALE //1300
CODNOTESP2 = S_NASCOSTO //1300
DESNOTESP2 = S_NASCOSTO //1300
CAUSTRASP = S_NORMALE //1400
DENCAUSTRASP = S_NORMALE //1400
CODVETT1 = S_NORMALE //1500
CODVETT2 = S_NORMALE //1500
CODVETT3 = S_NORMALE //1500
NOMEVETT1 = S_NORMALE //1500
NOMEVETT2 = S_NORMALE //1500
NOMEVETT3 = S_NORMALE //1500
NCOPIE = S_NASCOSTO //1600
IMPPAGATO = S_NORMALE //1800
ACCSALDO = S_NASCOSTO //1800
DOC1 = S_NASCOSTO //1900
DOC2 = S_NASCOSTO //1900
DOC3 = S_NASCOSTO //1900
ASPBENI1 = S_OBBLIGATORIO //2100
DESCRBENI1 = S_NORMALE //2100
ASPBENI2 = S_NASCOSTO //2100
DESCRBENI2 = S_NASCOSTO //2100
IMPNETTI = S_NASCOSTO //2200
RAGGR = S_NORMALE //2300
RAGGREFF = S_NORMALE //2300
SPESEINC = S_NORMALE //2400
ADDBOLLI = S_NORMALE //2400
CODNOTE = S_NORMALE //2500
NOTECLI = S_NOCHECK //2500
CAUSMAG = S_OBBLIGATORIO //2900
CAUSMAGC = S_DISABILITATO //2900
DESCRMAG = S_NORMALE //2900
DESCRMAGC = S_DISABILITATO //2900
DATACONS = S_NORMALE //2000
BLANK = S_DISABILITATO //4000
[DEFAULT]
[SHEET]
Col(0) = FR_JOLLY1|Albero|10
Col(1) = FR_CODMAG
Col(2) = FR_CODDEP
Col(3) = FR_CODART
Col(4) = FR_LIV1
Col(5) = FR_LIV2
Col(6) = FR_LIV3
Col(7) = FR_LIV4
Col(8) = FR_DESCR
Col(9) = FR_UMQTA
Col(10) = FR_QTA
Col(11) = FR_LORDO
Col(12) = FR_QTAEVASA
Col(13) = FR_RIGAEVASA
Col(14) = FR_DATACONS
Col(15) = FR_PREZZO
Col(16) = FR_SCONTO
Col(17) = FR_JOLLY2|K|25
Col(18) = FR_PERCPROV
Col(19) = FR_IMPFISUN
Col(20) = FR_IMPFISSO
Col(21) = FR_PERCPROV1
Col(22) = FR_CODIVA
Col(23) = FR_ADDIVA
Col(24) = FR_CAUS
Col(25) = FR_CODMAGC
Col(26) = FR_CODDEPC
Col(27) = FR_TIPORIGA
[RIGHE]
[HANDLERS]
[PROFILOGRUPPO]
101 = S_NASCOSTO
100 = S_NORMALE
200 = S_NORMALE
300 = S_NORMALE
400 = S_NORMALE
500 = S_NORMALE
600 = S_NORMALE
700 = S_NORMALE
800 = S_NORMALE
810 = S_NORMALE
820 = S_NORMALE
830 = S_NORMALE
900 = S_NORMALE
1000 = S_NORMALE
1100 = S_NORMALE
1200 = S_NORMALE
1210 = S_NORMALE
1300 = S_NORMALE
1400 = S_NORMALE
1500 = S_NORMALE
1600 = S_NASCOSTO
1800 = S_NORMALE
1900 = S_NORMALE
2000 = S_NORMALE
2100 = S_NASCOSTO
2200 = S_NORMALE
2300 = S_NORMALE
2400 = S_NORMALE
2500 = S_NORMALE
2900 = S_NORMALE
3000 = S_NORMALE
4000 = S_NORMALE
[ORDINEGRUPPI]
NGROUPS=27
1=100
2=2500
3=200
4=300
5=400
6=500
7=600
8=700
9=2400
10=2300
11=800
12=810
13=820
14=830
15=900
16=1100
17=1200
18=1500
19=1210
20=1300
21=1400
22=2100
23=1800
24=1000
25=2900
26=2000
27=3000