6840f1c595
Files correlati : Ricompilazione Demo : [ ] Commento : personalizzazione euroforesi (riporto sulla 10) git-svn-id: svn://10.65.10.50/branches/R_10_00@21567 c028cbd2-c16b-5b4b-a496-9718f37d4682
501 lines
14 KiB
C++
Executable File
501 lines
14 KiB
C++
Executable File
#include <applicat.h>
|
|
#include <automask.h>
|
|
#include <defmask.h>
|
|
#include <progind.h>
|
|
#include <recarray.h>
|
|
#include <recset.h>
|
|
|
|
#include <cfven.h>
|
|
#include "../ve/clifor.h"
|
|
#include "../ve/condv.h"
|
|
#include "../ve/rcondv.h"
|
|
#include "../ve/velib.h"
|
|
|
|
#include "ps1002.h"
|
|
#include "ps1002100a.h"
|
|
|
|
|
|
class TDoc_cache : public TCache
|
|
{
|
|
TString4 _codnum, _tipodoc;
|
|
int _anno;
|
|
long _codcf;
|
|
TDate _data;
|
|
|
|
protected:
|
|
virtual void discarding(const THash_object* obj);
|
|
virtual TObject* key2obj(const char* key);
|
|
|
|
public:
|
|
TDocumento& doc(const TToken_string& kdoc);
|
|
TDoc_cache(const char* codnum, const char* tipodoc, const TDate& datadoc, const long codcf);
|
|
};
|
|
|
|
//DISCARDING: salva un documento sul disco prima di eliminarlo dalla cache
|
|
void TDoc_cache::discarding(const THash_object* obj)
|
|
{
|
|
TDocumento& doc = (TDocumento&)obj->obj();
|
|
int err = doc.rewrite();
|
|
}
|
|
|
|
//KEY2OBJ:sceglie il documento giusto da disco in modo da poterlo continuare, o lo crea se non c'è
|
|
TObject* TDoc_cache::key2obj(const char* key)
|
|
{
|
|
TDocumento* doc = NULL;
|
|
|
|
TToken_string chiave(key);
|
|
|
|
const char provv = chiave.get(0)[0];
|
|
const int anno = chiave.get_int(1);
|
|
const TString& codnum = chiave.get(2);
|
|
const long ndoc = chiave.get_long(3);
|
|
|
|
doc = new TDocumento(provv, anno, codnum, ndoc);
|
|
|
|
if (ndoc <= 0)
|
|
{
|
|
doc->put(DOC_PROVV, 'D');
|
|
doc->put(DOC_ANNO, _anno);
|
|
doc->put(DOC_CODNUM, _codnum);
|
|
doc->put(DOC_NDOC, 0);
|
|
doc->put(DOC_TIPODOC, _tipodoc);
|
|
doc->put(DOC_STATO, 1);
|
|
doc->put(DOC_DATADOC, _data);
|
|
doc->put(DOC_TIPOCF, 'C');
|
|
doc->put(DOC_CODCF, _codcf);
|
|
|
|
doc->cli2doc(); //questo metodo riempie in automatico tutti i campi di testata collegati al cliente!
|
|
|
|
doc->put(DOC_CAUSMAG, doc->tipo().caus_mov()); //causale magazzino collegata al tipo
|
|
}
|
|
|
|
return doc;
|
|
}
|
|
|
|
//DOC: restituisce un puntatore ad un documento identificato dalla chiave documento completa
|
|
TDocumento& TDoc_cache::doc(const TToken_string& kdoc)
|
|
{
|
|
return *(TDocumento*)objptr(kdoc);
|
|
}
|
|
|
|
|
|
//metodo costruttore di una cache di 13 elementi
|
|
TDoc_cache::TDoc_cache(const char* codnum, const char* tipodoc, const TDate& datadoc, const long codcf) : TCache(13)
|
|
{
|
|
_codnum = codnum;
|
|
_tipodoc = tipodoc;
|
|
_anno = datadoc.year();
|
|
_data = datadoc;
|
|
_codcf = codcf;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// TAutomask
|
|
///////////////////////////////////////////////////////////
|
|
class TEdit_rdocs_mask : public TAutomask
|
|
{
|
|
int _pos_art, _pos_desc, _pos_um, _pos_qta, _pos_qtaev, _pos_prz, _pos_iva, _pos_lav, _pos_col,
|
|
_pos_dtprd_lav, _pos_qtaprd_lav, _pos_dtprd_col, _pos_qtaprd_col, _pos_num, _pos_anno,
|
|
_pos_provv, _pos_ndoc, _pos_nrig, _pos_desiva, _pos_deslav, _pos_descol;
|
|
|
|
protected:
|
|
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
|
|
void fill_sheet();
|
|
void save_sheet();
|
|
const TString4 find_um(const TString& codart) const;
|
|
const TString4 find_codiva(const TString& codart);
|
|
real find_prezzo_articolo(const TString& codart) const;
|
|
|
|
public:
|
|
TEdit_rdocs_mask();
|
|
~TEdit_rdocs_mask() {};
|
|
};
|
|
|
|
TEdit_rdocs_mask::TEdit_rdocs_mask() : TAutomask ("ps1002100a")
|
|
{
|
|
//assegna le posizioni delle colonne dello sheet
|
|
TSheet_field& sf_righe = sfield(F_RIGHE);
|
|
_pos_art = sf_righe.cid2index(S_CODART);
|
|
_pos_desc = sf_righe.cid2index(S_DESCR);
|
|
_pos_um = sf_righe.cid2index(S_UM);
|
|
_pos_qta = sf_righe.cid2index(S_QTA);
|
|
_pos_qtaev = sf_righe.cid2index(S_QTAEVASA);
|
|
_pos_prz = sf_righe.cid2index(S_PREZZO);
|
|
_pos_iva = sf_righe.cid2index(S_CODIVA);
|
|
_pos_lav = sf_righe.cid2index(S_LAV);
|
|
_pos_dtprd_lav = sf_righe.cid2index(S_DATAPROD_LAV);
|
|
_pos_qtaprd_lav = sf_righe.cid2index(S_QTAPROD_LAV);
|
|
_pos_col = sf_righe.cid2index(S_COLORE);
|
|
_pos_dtprd_col = sf_righe.cid2index(S_DATAPROD_COL);
|
|
_pos_qtaprd_col = sf_righe.cid2index(S_QTAPROD_COL);
|
|
_pos_num = sf_righe.cid2index(S_CODNUM);
|
|
_pos_anno = sf_righe.cid2index(S_ANNO);
|
|
_pos_provv = sf_righe.cid2index(S_PROVV);
|
|
_pos_ndoc = sf_righe.cid2index(S_NDOC);
|
|
_pos_nrig = sf_righe.cid2index(S_NRIGA);
|
|
|
|
_pos_desiva = sf_righe.cid2index(S_DESIVA);
|
|
_pos_deslav = sf_righe.cid2index(S_DESLAV);
|
|
_pos_descol = sf_righe.cid2index(S_DESCOL);
|
|
}
|
|
|
|
bool TEdit_rdocs_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
|
{
|
|
switch (o.dlg())
|
|
{
|
|
//maschera principale
|
|
case F_RIGHE:
|
|
if (e == se_notify_add) //righe aggiunte
|
|
{
|
|
TToken_string& riga_sheet = sfield(o.dlg()).row(jolly); //riga nuova dello sheet
|
|
const TString& codnum = get(F_CODNUM);
|
|
riga_sheet.add(codnum, _pos_num);
|
|
const int anno = get_date(F_DATADOC).year();
|
|
riga_sheet.add(anno, _pos_anno);
|
|
riga_sheet.add('D', _pos_provv);
|
|
}
|
|
|
|
if (e == se_query_del) //righe da eliminare
|
|
{
|
|
//solo le righe senza NDOC ed NRIGA possono essere eliminate!
|
|
TToken_string& riga_sheet = sfield(o.dlg()).row(jolly);
|
|
const long ndoc = riga_sheet.get_long(_pos_ndoc);
|
|
const int nriga = riga_sheet.get_int(_pos_nrig);
|
|
return ndoc == 0L || nriga == 0;
|
|
}
|
|
break;
|
|
|
|
//maschera di sheet
|
|
case S_CODART:
|
|
if (e == fe_modify)
|
|
{
|
|
//al cambio articolo deve proporre il codiva, la um, il prezzo
|
|
const TString& codart = o.get();
|
|
const TString& um = find_um(codart);
|
|
o.mask().set(S_UM, um);
|
|
const TString& codiva = find_codiva(codart);
|
|
o.mask().set(S_CODIVA, codiva);
|
|
const real prezzo = find_prezzo_articolo(codart);
|
|
o.mask().set(S_PREZZO, prezzo);
|
|
}
|
|
break;
|
|
|
|
case S_DATAPROD_LAV:
|
|
if (e == fe_modify)
|
|
{
|
|
//all'uscita dal campo deve proporre la qta prodotta in lavorazione pari alla qta sulla riga documento
|
|
const real qta = o.mask().get(S_QTA);
|
|
o.mask().set(S_QTAPROD_LAV, qta);
|
|
}
|
|
break;
|
|
case S_DATAPROD_COL:
|
|
if (e == fe_modify)
|
|
{
|
|
const real qta = o.mask().get(S_QTA);
|
|
o.mask().set(S_QTAPROD_COL, qta);
|
|
}
|
|
break;
|
|
|
|
//bottoni
|
|
case DLG_SELECT: //carica i record nello sheet in base al filtro di testata
|
|
if (e == fe_button)
|
|
{
|
|
if (check_fields())
|
|
{
|
|
disable(-1);
|
|
enable(-2);
|
|
fill_sheet();
|
|
}
|
|
}
|
|
break;
|
|
case DLG_CANCEL:
|
|
if (e == fe_button && jolly == 0)
|
|
{
|
|
disable(-2);
|
|
enable(-1);
|
|
sfield(F_RIGHE).destroy();
|
|
return false;
|
|
}
|
|
break;
|
|
case DLG_SAVEREC:
|
|
if (e == fe_button)
|
|
{
|
|
save_sheet();
|
|
fill_sheet();
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//cerca il codiva
|
|
const TString4 TEdit_rdocs_mask::find_codiva(const TString& codart)
|
|
{
|
|
const long codcf = get_long(F_CODCF);
|
|
TToken_string key_cfven;
|
|
key_cfven.add("C");
|
|
key_cfven.add(codcf);
|
|
TString4 codiva = cache().get(LF_CFVEN, key_cfven, CFV_ASSFIS);
|
|
if (codiva.empty())
|
|
codiva = cache().get(LF_ANAMAG, codart, ANAMAG_CODIVA);
|
|
|
|
return codiva;
|
|
}
|
|
|
|
//cerca la um standard del codart
|
|
const TString4 TEdit_rdocs_mask::find_um(const TString& codart) const
|
|
{
|
|
TToken_string key_umart;
|
|
key_umart.add(codart);
|
|
key_umart.add(1);
|
|
const TRectype& rec_umart = cache().get(LF_UMART, key_umart);
|
|
const TString4 um = rec_umart.get(UMART_UM);
|
|
return um;
|
|
}
|
|
|
|
//cerca prezzo in: contratto->listino->anamag
|
|
real TEdit_rdocs_mask::find_prezzo_articolo(const TString& codart) const
|
|
{
|
|
const long codcf = get_long(F_CODCF);
|
|
const TDate data_new_doc = get_date(F_DATADOC);
|
|
real prezzo = ZERO;
|
|
|
|
//0) anagrafica articolo (umart): mal che vada proporrà questa; va vergognosamente messa all'inizio e non alla fine..
|
|
//..perchè serve unità di misura un pò dappertutto
|
|
TToken_string key_umart;
|
|
key_umart.add(codart);
|
|
key_umart.add(1);
|
|
const TRectype& rec_umart = cache().get(LF_UMART, key_umart);
|
|
const TString4 um = rec_umart.get(UMART_UM);
|
|
const real umart_prezzo = rec_umart.get_real(UMART_PREZZO);
|
|
|
|
|
|
//1) contratto
|
|
//CONTRATTI: tipo=C|catven=|tipocf=C|codcf=codcf|cod=codcontr|tiporiga=A|codriga=codart|um=um
|
|
TString query_contr;
|
|
query_contr << "USE CONDV";
|
|
query_contr << "\nFROM TIPO=C TIPOCF=C CODCF=#CODCF";
|
|
query_contr << "\nTO TIPO=C TIPOCF=C CODCF=#CODCF";
|
|
|
|
TISAM_recordset recset_contr(query_contr);
|
|
recset_contr.set_var("#CODCF", codcf);
|
|
const long recset_contr_items = recset_contr.items();
|
|
//deve cercare un contratto in essere per la data del documento (in teoria ce ne dovrebbe essere 1 solo, oppure nessuno)
|
|
for (bool ok = recset_contr.move_first(); ok; ok = recset_contr.move_next())
|
|
{
|
|
const TDate dataini_c = recset_contr.get(CONDV_VALIN).as_date();
|
|
TDate datafin_c = recset_contr.get(CONDV_VALFIN).as_date();
|
|
if (!datafin_c.ok())
|
|
datafin_c = data_new_doc;
|
|
if (dataini_c <= data_new_doc && datafin_c >= data_new_doc)
|
|
{
|
|
TString4 codcontr = recset_contr.get(CONDV_COD).as_string();
|
|
|
|
//per um è necessario se il contratto scelto ha la gestione delle um accesa (tanto per complicarsi la vita)
|
|
const bool gestum_contr = recset_contr.get(CONDV_GESTUM).as_string() == "X";
|
|
|
|
TToken_string key_contr;
|
|
key_contr.add("C");
|
|
key_contr.add("");
|
|
key_contr.add("C");
|
|
key_contr.add(codcf);
|
|
key_contr.add("A");
|
|
key_contr.add(codart);
|
|
if (gestum_contr)
|
|
key_contr.add(um);
|
|
|
|
const TRectype& rec_contratto = cache().get(LF_RCONDV, key_contr);
|
|
const real contratto_prezzo = rec_contratto.get_real(RCONDV_PREZZO);
|
|
if (!contratto_prezzo.is_zero())
|
|
{
|
|
prezzo = contratto_prezzo;
|
|
break;
|
|
}
|
|
} //if (dataini_c <= data_new_doc...
|
|
} //for (bool ok = recset_contr.move_first()...
|
|
|
|
//se non ha trovato il prezzo sul contratto -> passa ai listini
|
|
|
|
//2) listino
|
|
//LISTINI: tipo=L|catven=catven|tipocf=|codcf=|cod=codlis|tiporiga=A|codriga=codart|um=um
|
|
if (prezzo.is_zero())
|
|
{
|
|
//usa una funzione automaggica dei clifor che raccatta il listino valido per il cliente in data del documento
|
|
TCli_for clifor('C', codcf);
|
|
const TString& codlist = clifor.find_listino_al(data_new_doc);
|
|
//se trova un listino valido raccatta il prezzo dalla riga
|
|
if (codlist.full())
|
|
{
|
|
TToken_string key_list;
|
|
key_list.add("L");
|
|
|
|
//la catven se c'è è del cliente
|
|
TToken_string key_cfven;
|
|
key_cfven.add("C");
|
|
key_cfven.add(codcf);
|
|
const TString& catven = cache().get(LF_CFVEN, key_cfven, CFV_CATVEN);
|
|
|
|
key_list.add(catven);
|
|
key_list.add("");
|
|
key_list.add("");
|
|
key_list.add(codlist);
|
|
|
|
const bool gestum_list = cache().get(LF_CONDV, key_list, CONDV_GESTUM) == "X";
|
|
|
|
key_list.add("A");
|
|
key_list.add(codart);
|
|
|
|
if (gestum_list)
|
|
key_list.add(um);
|
|
|
|
const TRectype& rec_listino = cache().get(LF_RCONDV, key_list);
|
|
const real listino_prezzo = rec_listino.get_real(RCONDV_PREZZO);
|
|
|
|
if (!listino_prezzo.is_zero())
|
|
prezzo = listino_prezzo;
|
|
}
|
|
} //if (prezzo.is_zero())...
|
|
|
|
//3) umart
|
|
if (prezzo.is_zero())
|
|
prezzo = umart_prezzo; //mal che vada sarà il prezzo di umart
|
|
|
|
return prezzo;
|
|
}
|
|
|
|
//funzione di ordinamento dello sheet in base al codart
|
|
static int sort_by_codart(TSheet_field& s, int r1, int r2)
|
|
{
|
|
const int pos = s.cid2index(S_CODART);
|
|
const char* a1 = s.cell(r1, pos);
|
|
const char* a2 = s.cell(r2, pos);
|
|
return strcmp(a1, a2);
|
|
}
|
|
|
|
//riempie lo sheet in base ai parametri di testata
|
|
void TEdit_rdocs_mask::fill_sheet()
|
|
{
|
|
//recordset con tutti i documenti non evasi nell'anno per il cliente selezionato
|
|
TString query;
|
|
query << "USE DOC KEY 2";
|
|
query << "\nSELECT (CODNUM=#CODNUM)&&(DOCEVASO!=\"X\")";
|
|
query << "\nFROM TIPOCF=C CODCF=#CODCF PROVV=D";
|
|
query << "\nTO TIPOCF=C CODCF=#CODCF PROVV=D";
|
|
|
|
TISAM_recordset recset(query);
|
|
|
|
recset.set_var("#CODCF", get_long(F_CODCF));
|
|
recset.set_var("#CODNUM", get(F_CODNUM));
|
|
|
|
const TString& lav = get(F_LAV);
|
|
const TString& col = get(F_COLORE);
|
|
const TString& codart = get(F_CODART);
|
|
|
|
const long items = recset.items();
|
|
const TRectype& rec = recset.cursor()->curr();
|
|
|
|
TSheet_field& sf_righe = sfield(F_RIGHE);
|
|
sf_righe.destroy();
|
|
|
|
TProgind pi(items, TR("Caricamento documenti in corso..."), true, true);
|
|
int k = 0;
|
|
|
|
for (bool ok = recset.move_first(); ok; ok = recset.move_next())
|
|
{
|
|
if (!pi.addstatus(1))
|
|
break;
|
|
|
|
//per ogni documento prende le sole righe non evase e le carica sullo sheet
|
|
TDocumento doc(rec);
|
|
FOR_EACH_PHYSICAL_RDOC(doc, r, rdoc)
|
|
{
|
|
if (!rdoc->is_evasa() && rdoc->is_evadibile())
|
|
{
|
|
if (lav.full() && rdoc->get(RDOC_CODCMS) != lav)
|
|
continue;
|
|
if (col.full() && rdoc->get(RDOC_FASCMS) != col)
|
|
continue;
|
|
if (codart.full() && rdoc->get(RDOC_CODART) != codart)
|
|
continue;
|
|
|
|
sf_righe.autoload_line(++k, *rdoc); //aggiunge una riga nuova riempiendola con tutti i campi che hanno FIELD nella maschera
|
|
}
|
|
}
|
|
}
|
|
|
|
//richiesta del cazzo della euroforesi: ordinare le righe per codart; si sono poi resi conto loro stessi che era..
|
|
//..una richiesta del cazzo e l'hanno abbandonata
|
|
//sf_righe.sort(sort_by_codart);
|
|
sf_righe.force_update();
|
|
}
|
|
|
|
//salva losheet con eventuali modifiche e nuove righe
|
|
void TEdit_rdocs_mask::save_sheet()
|
|
{
|
|
const TString& codnum = get(F_CODNUM);
|
|
const TString& tipodoc = get(F_TIPODOC);
|
|
const TDate datadoc = get_date(F_DATADOC);
|
|
const long codcf = get_long(F_CODCF);
|
|
|
|
TDoc_cache doc_cache(codnum, tipodoc, datadoc, codcf);
|
|
|
|
TSheet_field& sf_righe = sfield(F_RIGHE);
|
|
|
|
FOR_EACH_SHEET_ROW(sf_righe, r, row)
|
|
{
|
|
TToken_string key;
|
|
key.add(row->get(_pos_provv));
|
|
key.add(row->get(_pos_anno));
|
|
key.add(row->get(_pos_num));
|
|
key.add(row->get(_pos_ndoc));
|
|
|
|
int nriga = row->get_int(_pos_nrig);
|
|
|
|
TDocumento& curr_doc = doc_cache.doc(key);
|
|
if (nriga <= 0)
|
|
{
|
|
const TRiga_documento& rdoc = curr_doc.new_row("01"); //solo righe merce sono aggiungibili
|
|
nriga = rdoc.get_int(RDOC_NRIGA);
|
|
row->add(curr_doc.get_long(DOC_NDOC), _pos_ndoc);
|
|
row->add(nriga, _pos_nrig);
|
|
}
|
|
|
|
sf_righe.autosave_line(r + 1, curr_doc[nriga]); //salva maggicamente la riga nuova
|
|
}
|
|
|
|
doc_cache.destroy();
|
|
}
|
|
|
|
|
|
///////////////////////////////////////
|
|
// TSkeleton_application
|
|
///////////////////////////////////////
|
|
class TEdit_rdocs : public TSkeleton_application
|
|
{
|
|
protected:
|
|
virtual bool check_autorization() const { return false; }
|
|
virtual const char* extra_modules() const { return "ve"; }
|
|
virtual void main_loop();
|
|
virtual bool create();
|
|
};
|
|
|
|
void TEdit_rdocs::main_loop()
|
|
{
|
|
TEdit_rdocs_mask mask;
|
|
mask.run();
|
|
}
|
|
|
|
bool TEdit_rdocs::create()
|
|
{
|
|
open_files(LF_DOC, LF_RIGHEDOC, 0);
|
|
return TSkeleton_application::create();
|
|
}
|
|
|
|
int ps1002100 (int argc, char* argv[])
|
|
{
|
|
TEdit_rdocs main_app;
|
|
main_app.run(argc, argv, TR("Gestione righe per cliente"));
|
|
return true;
|
|
} |