Files correlati : Ricompilazione Demo : [ ] Commento :prima implementazione ripartizioni costo/ricavo a saldi (da provare del tutto!) git-svn-id: svn://10.65.10.50/trunk@19232 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			499 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			499 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| #include <automask.h>
 | ||
| #include <recarray.h>
 | ||
| #include <recset.h>
 | ||
| #include <relapp.h>
 | ||
| 
 | ||
| #include "ca0800a.h"
 | ||
| #include "calib01.h"
 | ||
| 
 | ||
| #include "fasi.h"
 | ||
| #include "rip.h"
 | ||
| #include "rrip.h"
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // TRiparti_msk 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| class TRiparti_msk : public TAutomask
 | ||
| {
 | ||
| protected:
 | ||
|   virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
 | ||
|   int create_sheet_fields(int lf, int& y, short& dlg);
 | ||
|   void genera_righe_fasi();
 | ||
|   void create_sheet();
 | ||
| 
 | ||
| public:
 | ||
|   TRiparti_msk();
 | ||
| };
 | ||
| 
 | ||
| void TRiparti_msk::genera_righe_fasi()
 | ||
| {
 | ||
|   //data una commessa in ingresso, la si vuole ripartire sulle sue fasi
 | ||
|   TString80 commessa;
 | ||
|   for (short id = F_CODCMS_1; id2pos(id) > 0; id++)
 | ||
|     commessa << get(id);
 | ||
| 
 | ||
|   if (commessa.full())
 | ||
|   {
 | ||
|     //sheet della maschera da riempire
 | ||
|     TSheet_field& sheet = sfield(F_SHEET);
 | ||
|     sheet.destroy();
 | ||
|     //quali sono le fasi legate a 'sto cavolo di commessa?
 | ||
|     TISAM_recordset fasi("USE FASI\nFROM CODCMSFAS=#COMMESSA\nTO CODCMSFAS=#COMMESSA");
 | ||
|     fasi.set_var("#COMMESSA", TVariant(commessa));
 | ||
|     TToken_string wts;
 | ||
|     for (bool ok = fasi.move_first(); ok; ok = fasi.move_next())
 | ||
| 	  {
 | ||
|       wts = " ";
 | ||
|       wts.add(commessa);
 | ||
|       wts.add(fasi.get(FASI_CODFASE).as_string());
 | ||
|       sheet.row(-1) = wts;
 | ||
|     }
 | ||
|     sheet.force_update(); //scrive le righe effettivamente
 | ||
|   } //if(commessa.full()...
 | ||
| }
 | ||
| 
 | ||
| bool TRiparti_msk::on_field_event(TOperable_field& o, TField_event e, long jolly)
 | ||
| {
 | ||
|   switch (o.dlg())
 | ||
|   {
 | ||
|     //gestione tipo di ripartizioni possibili
 | ||
|     //0 = percentuale; 1 = in base al peso economico della commessa; 2 = per parti (modello cocktail)
 | ||
|   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());
 | ||
|       switch (t)
 | ||
|       {
 | ||
|       case 0: //percentuale
 | ||
|         {
 | ||
|           sm.hide(201);
 | ||
|           sm.show(101);
 | ||
|           sm.enable(101);
 | ||
|           sf.enable_column(0);
 | ||
|         }
 | ||
|         break;
 | ||
|       case 1: //peso economico della commessa (non viene specificato nulla, la ripartizione avviene in base ai saldi)
 | ||
|         {
 | ||
|           sm.show(101);
 | ||
|           sm.disable(101);  //necessario per non avere 2 campi abilitati e nascosti nella stessa posizione (d<> errore)
 | ||
|           sm.hide(201);
 | ||
|           sf.enable_column(0, false);
 | ||
|         }
 | ||
|         break;
 | ||
|       case 2: //parti
 | ||
|         {
 | ||
|           sm.hide(101);
 | ||
|           sm.show(201);
 | ||
|           sm.enable(201);
 | ||
|           sf.enable_column(0);
 | ||
|         }
 | ||
|         break;
 | ||
|       }
 | ||
| 
 | ||
|       sf.force_update();
 | ||
|     }
 | ||
|     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 ripartizione deve essere 100"));
 | ||
|     }
 | ||
|     break;
 | ||
|   case F_GENFASI:
 | ||
|     if (e == fe_init)
 | ||
|     {
 | ||
|       bool accendimi = insert_mode();
 | ||
|       if (accendimi)
 | ||
|       {
 | ||
|         const TMultilevel_code_info& fasinfo = ca_multilevel_code_info(LF_FASI);
 | ||
|         accendimi = fasinfo.parent() == LF_COMMESSE;
 | ||
|       }
 | ||
|       o.show(accendimi);
 | ||
|     }
 | ||
|     if (e == fe_button)
 | ||
|       genera_righe_fasi();
 | ||
|     break;
 | ||
|   default:
 | ||
|     break;
 | ||
|   }
 | ||
|   return true;
 | ||
| }
 | ||
| 
 | ||
| int TRiparti_msk::create_sheet_fields(int lf, int& y, short& dlg)
 | ||
| {
 | ||
|   TSheet_field& sf = sfield(F_SHEET);
 | ||
|   TMask& sm = sf.sheet_mask();
 | ||
|   const int h = ca_create_fields(sm, 0, lf, 1, y, dlg, dlg+50);
 | ||
| 
 | ||
|   for (int i = 0; i < h; i++)
 | ||
|   {
 | ||
|     TEdit_field& fld = sm.efield(dlg+i);
 | ||
|     int logic = lf;
 | ||
|     if (logic == LF_FASI)
 | ||
|     {
 | ||
|       const TMultilevel_code_info& fasinfo = ca_multilevel_code_info(LF_FASI);
 | ||
|       if (fasinfo.parent() != 0)
 | ||
|       {
 | ||
|         const TMultilevel_code_info& parinfo = ca_multilevel_code_info(fasinfo.parent());
 | ||
|         if (i < parinfo.levels())
 | ||
|           logic = fasinfo.parent();
 | ||
|       }
 | ||
|     }
 | ||
| 
 | ||
|     if (logic == LF_PCON)
 | ||
|     {
 | ||
|       const TFieldref* f = fld.field();
 | ||
|       const TString16 fieldname = f->name();
 | ||
| 
 | ||
|       if (fieldname == "GRUPPO") 
 | ||
|         fld.set_field("CODCONTO[1,3]"); else
 | ||
|       if (fieldname == "CONTO") 
 | ||
|         fld.set_field("CODCONTO[4,6]"); else
 | ||
|       if (fieldname == "SOTTOCONTO") 
 | ||
|         fld.set_field("CODCONTO[7,12]");
 | ||
|     }
 | ||
|     else
 | ||
|     {
 | ||
|       const char* fieldname = NULL;
 | ||
|       switch(logic)
 | ||
|       {
 | ||
|       case LF_CDC     : fieldname = RRIP_CODCOSTO; break;
 | ||
|       case LF_COMMESSE: fieldname = RRIP_CODCMS;   break;
 | ||
|       case LF_FASI    : fieldname = RRIP_CODFASE;  break;
 | ||
|       default         : fieldname = RRIP_CODCONTO; break;
 | ||
|       }
 | ||
|       TFieldref* f = (TFieldref*)fld.field();
 | ||
|       f->set_name(fieldname);
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   y += h+1;
 | ||
|   dlg += h;
 | ||
|   return h;
 | ||
| }
 | ||
| 
 | ||
| void TRiparti_msk::create_sheet()
 | ||
| {
 | ||
|   TSheet_field& sf = sfield(F_SHEET);
 | ||
|   TMask& sm = sf.sheet_mask();
 | ||
|   sm.hide(-1);
 | ||
| 
 | ||
|   const TMultilevel_code_info& fasinfo = ca_multilevel_code_info(LF_FASI);
 | ||
| 
 | ||
| 	TConfig& ini = ca_config();
 | ||
| 
 | ||
|   int y = 1;
 | ||
|   short dlg = 202;
 | ||
| 
 | ||
|   for (int i = 0; i < 2; i++)
 | ||
|   {
 | ||
|     const TString& level = ini.get("Level", NULL, i+1);  // Legge il livello 1 o 2
 | ||
|     if (level == "CDC")                                  // Crea centro di costo 
 | ||
|     {
 | ||
|       if (fasinfo.parent() == LF_CDC)
 | ||
|         create_sheet_fields(LF_FASI, y, dlg);
 | ||
|       else
 | ||
|         create_sheet_fields(LF_CDC, y, dlg);
 | ||
|     } else
 | ||
|     if (level == "CMS")                                   // Crea commessa
 | ||
|     {
 | ||
|       if (fasinfo.parent() == LF_COMMESSE)
 | ||
|         create_sheet_fields(LF_FASI, y, dlg);
 | ||
|       else
 | ||
|         create_sheet_fields(LF_COMMESSE, y, dlg);
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   if (fasinfo.levels() > 0 && fasinfo.parent() <= 0)
 | ||
|     create_sheet_fields(LF_FASI, y, dlg);
 | ||
| 
 | ||
|   const bool use_pdc = ini.get_bool("UsePdcc");
 | ||
|   create_sheet_fields(use_pdc ? LF_PCON : LF_PCONANA, y, dlg);
 | ||
|   
 | ||
|   for (short id = 217; id >= 202; id--)
 | ||
|   {
 | ||
|     const int pos = sm.id2pos(id);
 | ||
|     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_justify(id, f.is_kind_of(CLASS_REAL_FIELD));
 | ||
|       sf.set_column_width(id, (max(3+size, prompt.len()+1)) * CHARX);
 | ||
|     }
 | ||
|     else
 | ||
|     {
 | ||
|       sf.delete_column(id);
 | ||
|     }
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| TRiparti_msk::TRiparti_msk() : TAutomask("ca0800a") 
 | ||
| {  
 | ||
| 	TConfig& ini = ca_config();
 | ||
| 
 | ||
|   // Crea gli eventuali campi per commessa e centro di costo
 | ||
|   const TMultilevel_code_info& fasinfo = ca_multilevel_code_info(LF_FASI);
 | ||
|   int y = 11;
 | ||
|   for (int i = 0; i < 2; i++)
 | ||
|   {
 | ||
|     const char* prompt = NULL;
 | ||
|     int h = 0;
 | ||
|     const TString& level = ini.get("Level", NULL, i+1);  // Legge il livello 1 o 2
 | ||
|     if (level == "CDC")                                  // Crea centro di costo 
 | ||
|     {
 | ||
|       h = ca_create_fields(*this, 0, LF_CDC, 2,  y, F_CODCDC_1, F_DESCDC_1);
 | ||
|       prompt = TR("@bCentro di costo");
 | ||
|     } else
 | ||
|     if (level == "CMS")                                   // Crea commessa
 | ||
|     {
 | ||
|       if (fasinfo.parent() == LF_COMMESSE)
 | ||
|       {
 | ||
|         h = ca_create_fields(*this, 0, LF_FASI, 2, y, F_CODCMS_1, F_DESCMS_1);
 | ||
|         prompt = TR("@bCommessa/Fase");
 | ||
| 
 | ||
|         const TMultilevel_code_info& cmsinfo = ca_multilevel_code_info(LF_COMMESSE);
 | ||
|         const int cmslevels = cmsinfo.levels();
 | ||
|         for (int j = 0; j < cmslevels; j++)
 | ||
|         {
 | ||
|           TEdit_field& cfld = efield(F_CODCMS_1+j);
 | ||
|           const TFieldref& fr = cmsinfo.fieldref(j);
 | ||
|           TString80 str = RIP_CODCMS; 
 | ||
|           if (cmslevels > 1)
 | ||
|             str.format("%s[%d,%d]", RIP_CODCMS, fr.from()+1, fr.to());
 | ||
|           cfld.set_field(str);
 | ||
|         }
 | ||
|       }
 | ||
|       else
 | ||
|       {
 | ||
|         h = ca_create_fields(*this, 0, LF_COMMESSE, 2, y, F_CODCMS_1, F_DESCMS_1);
 | ||
|         prompt = TR("@bCommessa");
 | ||
|       }
 | ||
|     } else
 | ||
|     if (level == "FSC" && fasinfo.parent() <= 0)
 | ||
|     {
 | ||
|       h = ca_create_fields(*this, 0, LF_FASI, 2, y, F_CODCMS_1, F_DESCMS_1);
 | ||
|       prompt = TR("@bFase");
 | ||
|     }
 | ||
| 
 | ||
|     if (prompt != NULL)                                   // Crea groupbox
 | ||
|     {
 | ||
|       const int last = fields()-1;
 | ||
|       for (int j = 0; j < 2*h; j++)
 | ||
|         fld(last-j).set_group(2);
 | ||
| 
 | ||
|       h += 2;
 | ||
|       TGroup_field& grp = add_groupbox(F_LEVEL_1+i, 0, prompt, 1, y-1, 78, h);
 | ||
|       grp.set_group(2);
 | ||
|       y += h;
 | ||
|     }
 | ||
|   }
 | ||
|   create_sheet();
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| // TRiparti_app
 | ||
| ///////////////////////////////////////////////////////////
 | ||
| 
 | ||
| class TRiparti_app : public TRelation_application
 | ||
| {  
 | ||
|   TRelation* _rel;
 | ||
|   TRiparti_msk* _msk;
 | ||
| 
 | ||
|   const TString& somma_campi(TToken_string& row, int first, bool pdc = false) const;
 | ||
|   void write_rows();
 | ||
| 
 | ||
|   void spezza_campo(const TString& str, TToken_string& row, int first) const;
 | ||
|   void read_rows();
 | ||
| 
 | ||
| protected:
 | ||
|   virtual const char * extra_modules() const {return "cm";} //funziona anche con autorizzazione CM
 | ||
| 
 | ||
|   virtual bool user_create();
 | ||
|   virtual bool user_destroy();
 | ||
|   virtual int write(const TMask& m);
 | ||
|   virtual int rewrite(const TMask& m);
 | ||
|   virtual int read(TMask& m);
 | ||
|   virtual bool get_next_key(TToken_string& key);
 | ||
| 
 | ||
|   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, bool pdc) const
 | ||
| {
 | ||
|   TSheet_field& sheet = _msk->sfield(F_SHEET);
 | ||
|   TMask& m = sheet.sheet_mask();
 | ||
|   
 | ||
|   const short id = 201 + first;
 | ||
| 
 | ||
|   TString& str = get_tmp_string(20);
 | ||
|   for (int i = 0; i < 4; i++)
 | ||
|   {
 | ||
|     TString80 token = row.get(first+i);
 | ||
|     if (m.id2pos(id+i) < 0)
 | ||
|       break;
 | ||
|     const TEdit_field& fld = m.efield(id+i);
 | ||
|     if (pdc)
 | ||
|       token.right_just(fld.size(), '0');
 | ||
|     else
 | ||
|       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();
 | ||
|   TString80 token;
 | ||
| 
 | ||
|   const short id = 201 + first;
 | ||
|   int start = 0;
 | ||
|   for (int i = 0; i < 4; i++)
 | ||
|   {
 | ||
|     if (m.id2pos(id+i) < 0)
 | ||
|       break;
 | ||
|     const TEdit_field& fld = m.efield(id+i);
 | ||
|     const int len = fld.size();
 | ||
|     token = str.mid(start, len); token.trim();
 | ||
|     row.add(token, first+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);
 | ||
|   TMask& sm = sheet.sheet_mask();
 | ||
| 
 | ||
|   FOR_EACH_SHEET_ROW(sheet, i, row)
 | ||
|   {
 | ||
|     TRectype& rec = a.row(i+1, true);  // Crea una riga nuova
 | ||
|     for (int i = sm.fields()-1; i >= 0; i--)
 | ||
|     {
 | ||
|       TMask_field& mf = sm.fld(i);
 | ||
|       if (mf.field() != NULL)
 | ||
|       {
 | ||
|         const int idx = sheet.cid2index(mf.dlg());
 | ||
|         if (idx < 17)
 | ||
|           mf.field()->write(row->get(idx), rec);
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
|   a.rewrite();
 | ||
| }
 | ||
| 
 | ||
| void TRiparti_app::read_rows()
 | ||
| {
 | ||
|   const char tipo = _msk->get(F_TIPO)[0];
 | ||
|   TToken_string key;
 | ||
|   key << tipo << '|' << _msk->get(tipo == 'B' ? F_CODICE_B : F_CODICE_I);
 | ||
|   TRecord_array a(key, LF_RRIP);
 | ||
|   
 | ||
|   TSheet_field& sheet = _msk->sfield(F_SHEET);
 | ||
|   TMask& sm = sheet.sheet_mask();
 | ||
|   sheet.destroy();
 | ||
|   for (int i = 1; i <= a.rows(); i++)
 | ||
|   {
 | ||
|     TToken_string& row = sheet.row(i-1);
 | ||
|     const TRectype& rec = a.row(i);
 | ||
|     for (int i = sm.fields()-1; i >= 0; i--)
 | ||
|     {
 | ||
|       TMask_field& mf = sm.fld(i);
 | ||
|       if (mf.field() != NULL)
 | ||
|       {
 | ||
|         const int idx = sheet.cid2index(mf.dlg());
 | ||
|         if (idx < 17)
 | ||
|           row.add(mf.field()->read(rec), idx);
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| bool TRiparti_app::get_next_key(TToken_string& key)
 | ||
| { 
 | ||
|   long num = 1;
 | ||
|   
 | ||
|   const char tipo = _msk->get(F_TIPO)[0];
 | ||
|   TString query;
 | ||
|   query << "USE RIP\nFROM TIPO=" << tipo << "\nTO TIPO=" << tipo;
 | ||
|   TISAM_recordset rip_recset(query);
 | ||
|   const long items = rip_recset.items();
 | ||
| 
 | ||
|   if (rip_recset.move_last())
 | ||
|     num += rip_recset.get(RIP_CODICE).as_int();
 | ||
| 
 | ||
|   //la scelta del campo della maschera su cui scrivere dipende dal tipo di ripartizione scelta nel radiobutton dei tipi
 | ||
|   long codice = F_CODICE_I;
 | ||
|   if (tipo == 'B')
 | ||
|     codice = F_CODICE_B;
 | ||
| 
 | ||
|   key.format("%d|%c|%d|%ld", F_TIPO, tipo, codice, num);
 | ||
|   return true; 
 | ||
| }
 | ||
| 
 | ||
| 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;
 | ||
| }
 | ||
| 
 | ||
| int TRiparti_app::read(TMask& m)
 | ||
| {
 | ||
|   const int err = TRelation_application::read(m);
 | ||
|   if (err == NOERR)
 | ||
|     read_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;
 | ||
| }
 | ||
| 
 |