53cc21039d
Files correlati : lv2 lv3 lv3200a.msk lvmenu Ricompilazione Demo : [ ] Commento : 1. Il programma di Evasione buoni di prelievo Non deve visualizzare le righe che hanno la quantità da consegnare = a 0 Che siano causali di solo ritiro o quantità che non fanno consegna risolviamo comunque tutte le casistiche Per definizione sono già evase, non avendo una quantità da consegnare ma solo da ritirare. Quando creiamo il buono di consegna dal buono di prelievo mettere anche queste righe. (cosa che il programma già fa se metto io a mano il flag di evaso) 2. Quando entro in evasione del buono di prelievo e premo annulla mi deve chiedere se salvare le modifiche (come fa il pulsante salva) e darmi la possibilità di scegliere un altro buono di prelievo Adesso invece mi constringe a uscire e rientrare da menu per passare da un buono allaltro Il default per la ricerca dei buoni di prelievo del campo stato deve essere impostato a 1 3. Se entro nel dettaglio di una riga delevasione del buono di prelievo (cliccando 2 volte sul campo consegnato) il pulsante annulla non fa niente 4. Sullevasione del buono di prelievo , sui campi riferimenti ritiro e consegna non ci scrive niente 5. La data di prevista consegna sullevasione dei buoni di prelievo non serve quindi la toglierei dalla visualizzazione guadagnamo lo spazio per scrivere accanto alla data del documento , subito dopo i dati dellesercizio, la descrizione Data Bolla 6. La data del buono di consegna , quando lo generiamo dal buono di prelievo, deve essere quella della data del punto 5 , che essendo modificabile permette di fare bolle di consegna anche con unaltra data. Ora le crea con la data del giorno 7. nel programma di evasione buoni di prelievo , quando metto la quantità , mi calcola i pacchi . ma se metto una quantità che non fa pacco non me la consedera. Esempio Quantità per confezione 40 quantità consegnata 45 i pacchi sono 2 non 1 Quantità per confezione 40 quantità consegnata 5 i pacchi sono 1 non 0 9. Quando creo il buono di consegna da buono di prelievo mi deve chiedere se voglio stampare il buono di consegna (come il punto 8) git-svn-id: svn://10.65.10.50/trunk@19547 c028cbd2-c16b-5b4b-a496-9718f37d4682
831 lines
23 KiB
C++
Executable File
831 lines
23 KiB
C++
Executable File
#include <applicat.h>
|
|
#include <automask.h>
|
|
#include <defmask.h>
|
|
#include <execp.h>
|
|
#include <utility.h>
|
|
|
|
#include "lvlib.h"
|
|
|
|
#include "lvcondv.h"
|
|
#include "lvrcondv.h"
|
|
#include "lvrconsplan.h"
|
|
#include "../mg/clifogiac.h"
|
|
|
|
#include "lv2900a.h"
|
|
|
|
|
|
////////////////////////////
|
|
//// TBUONI_CACHE ////
|
|
////////////////////////////
|
|
|
|
//classe TBuoni_cache
|
|
class TBuoni_cache : public TCache
|
|
{
|
|
TString4 _codnum, _tipodoc, _stato;
|
|
long _ndoc;
|
|
|
|
protected:
|
|
virtual void discarding(const THash_object* obj);
|
|
virtual TObject* key2obj(const char* key);
|
|
|
|
public:
|
|
TDocumento& doc(const TDate& gg, const long cc);
|
|
TBuoni_cache();
|
|
};
|
|
|
|
//DISCARDING: metodo che salva un documento sul disco prima di eliminarlo dalla cache
|
|
void TBuoni_cache::discarding(const THash_object* obj)
|
|
{
|
|
TDocumento& doc = (TDocumento&)obj->obj();
|
|
int err = doc.rewrite();
|
|
}
|
|
|
|
//KEY2OBJ: metodo che sceglie il documento giusto da disco in modo da poterlo continuare, o lo crea se non c'è
|
|
TObject* TBuoni_cache::key2obj(const char* key)
|
|
{
|
|
TToken_string chiave(key);
|
|
TDate datadoc = chiave.get();
|
|
const TDate datagen(TODAY);
|
|
TDate dadata = datadoc;
|
|
TDate adata = datagen;
|
|
adata.addmonth();
|
|
const long codcf = chiave.get_long();
|
|
|
|
if(_ndoc == 0)
|
|
{
|
|
TString query2;
|
|
query2 << "USE DOC\n"
|
|
<< "FROM PROVV=\"D\" ANNO=" << datadoc.year() << " CODNUM=\"" << _codnum << "\"\n"
|
|
<< "TO PROVV=\"D\" ANNO=" << datadoc.year() << " CODNUM=\"" << _codnum << "\"";
|
|
TISAM_recordset sporco(query2);
|
|
sporco.move_last();
|
|
_ndoc = sporco.get(DOC_NDOC).as_int();
|
|
}
|
|
|
|
TString query = "USE DOC KEY 2\n";
|
|
query << "SELECT (TIPODOC=\"" << _tipodoc << "\")&&(STATO=\"" << _stato <<"\")\n";
|
|
query << "FROM TIPOCF=C CODCF=" << codcf << " PROVV=D ANNO=" << datadoc.year() << " DATADOC=" << datadoc << " CODNUM=" << _codnum << "\n";
|
|
query << "TO TIPOCF=C CODCF=" << codcf << " PROVV=D ANNO=" << datadoc.year() << " DATADOC=" << datadoc << " CODNUM=" << _codnum << "\n";
|
|
TISAM_recordset rset(query);
|
|
|
|
TDocumento* doc = NULL;
|
|
|
|
if (rset.move_first())
|
|
doc = new TDocumento(rset.cursor()->curr());
|
|
else
|
|
{
|
|
TLaundry_contract cont(codcf, 0, datadoc);
|
|
const TString8 codcont = cont.get(LVCONDV_CODCONT);
|
|
|
|
TString query1 = "USE LVRCONSPLAN KEY 3\n";
|
|
query1 << "FROM CODCF=" << codcf << " CODCONT=" << codcont << " DTCONS=#DADATA\n";
|
|
query1 << "TO CODCF=" << codcf << " CODCONT=" << codcont << " DTCONS=#ADATA\n";
|
|
TISAM_recordset consegne(query1);
|
|
consegne.set_var("#DADATA", ++dadata);
|
|
consegne.set_var("#ADATA", adata);
|
|
consegne.move_first();
|
|
const TDate dataprco = consegne.get(LVRCONSPLAN_DTCONS).as_date();
|
|
const int coditi = consegne.get(LVRCONSPLAN_CODITI).as_int();
|
|
|
|
doc = new TDocumento('D', datadoc.year(), _codnum, ++_ndoc);
|
|
doc->put(DOC_TIPODOC, _tipodoc);
|
|
doc->put(DOC_STATO, _stato);
|
|
doc->put(DOC_DATADOC, datadoc);
|
|
doc->put(DOC_TIPOCF, 'C');
|
|
doc->put(DOC_CODCF, codcf);
|
|
doc->put(DOC_CODCONT, codcont);
|
|
doc->put("DATACON", datadoc); //data conteggio
|
|
doc->put("DATAGEN", datagen); //data generazione del documento
|
|
doc->put("DATAPRCO", dataprco); //data prevista consegna
|
|
doc->put("CODITI", coditi); //codice itinerario
|
|
}
|
|
return doc;
|
|
}
|
|
|
|
//DOC: metodo che restituisce un puntatore ad un documento identificato dalla coppia data - cliente
|
|
TDocumento& TBuoni_cache::doc(const TDate& gg, const long cc)
|
|
{
|
|
TString16 key;
|
|
key << gg.date2ansi() << '|' << cc;
|
|
return *(TDocumento*)objptr(key);
|
|
}
|
|
|
|
//metodo costruttore di una cache di 17 elementi
|
|
TBuoni_cache::TBuoni_cache() : TCache(17)
|
|
{
|
|
_codnum = ini_get_string(CONFIG_DITTA, "lv", "NUM_GEN");
|
|
_tipodoc = ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_GEN");
|
|
_stato = cache().get("%TIP", _tipodoc, "S2").left(1);
|
|
|
|
_ndoc = 0;
|
|
}
|
|
|
|
/////////////////////////////////
|
|
//// TCONTA_PULITO_MSK ////
|
|
/////////////////////////////////
|
|
|
|
//classe TConta_pulito_msk
|
|
class TConta_pulito_msk: public TAutomask
|
|
{
|
|
TString4 _auto;
|
|
TString4 _giri;
|
|
bool _percli;
|
|
bool _permag;
|
|
long _codcf;
|
|
TString4 _print;
|
|
|
|
protected:
|
|
virtual bool on_field_event(TOperable_field& o,TField_event e,long jolly);
|
|
|
|
bool elabora_file(const TFilename& file);
|
|
void sposta_file(const TFilename& file);
|
|
bool genera_documenti(const TFilename& file, TAssoc_array& documenti);
|
|
void prepara_movimenti(const TFilename& file, TAssoc_array& movimenti);
|
|
bool genera_movmag(TAssoc_array& movimenti);
|
|
|
|
public:
|
|
TConta_pulito_msk();
|
|
};
|
|
|
|
//ON_FIELD_EVENT: metodo che gestisce gli eventi sui campi della maschera
|
|
bool TConta_pulito_msk::on_field_event(TOperable_field& f,TField_event e,long jolly)
|
|
{
|
|
//prendo il path dalla maschera
|
|
const TString& path = get(F_PATH);
|
|
const TString& fname = get(F_FNAME);
|
|
TFilename file = path;
|
|
file.add(fname);
|
|
|
|
TAssoc_array documenti;
|
|
TAssoc_array movimenti;
|
|
|
|
//a seconda del bottone premuto esegui un metodo diverso
|
|
switch (f.dlg())
|
|
{
|
|
case DLG_IMPORT:
|
|
if(e == fe_button)
|
|
{
|
|
if (elabora_file(file))
|
|
{
|
|
sposta_file(file);
|
|
message_box(TR("Importazione dei dati terminata"));
|
|
}
|
|
}
|
|
break;
|
|
case DLG_PACKTCLI:
|
|
if(e == fe_button)
|
|
{
|
|
genera_documenti(file, documenti);
|
|
|
|
if (documenti.items() > 0)
|
|
{
|
|
//capisci se devi stampare dalla maschera se non è stato lanciato da linea di comando
|
|
char print = _print[0];
|
|
if (_print.empty())
|
|
print = get_bool(F_STAMPA) ? 'S' : 'N';
|
|
|
|
if (print == 'S')
|
|
{
|
|
//preparo il pezzo fisso della linea di comando per richiamare la stampa dei documenti
|
|
TDoc_key kd(documenti.get_hashobj()->key());
|
|
const TString4 codnum = kd.codnum();
|
|
const int anno = kd.anno();
|
|
const char provv = kd.provv();
|
|
|
|
//lancia la stampa dei documenti ve1 -2 per ogni documento preparato
|
|
TString80 str;
|
|
str << "ve1 -2 " << codnum << ' ' << anno << ' ' << provv << ' ';
|
|
|
|
FOR_EACH_ASSOC_OBJECT(documenti, obj, key, itm)
|
|
{
|
|
TDoc_key kdoc(key);
|
|
const int ndoc = kdoc.ndoc();
|
|
|
|
TString80 lcom = str;
|
|
lcom << ndoc << " S";
|
|
|
|
TExternal_app stampa(lcom);
|
|
stampa.run();
|
|
}
|
|
}
|
|
message_box(TR("Generazione dei documenti terminata"));
|
|
}
|
|
else
|
|
message_box(TR("Non è stato possibile generare nessun documento con i parametri fissati"));
|
|
}
|
|
break;
|
|
case DLG_PACKTMAG:
|
|
if(e == fe_button)
|
|
{
|
|
prepara_movimenti(file, movimenti);
|
|
if (movimenti.items() > 0)
|
|
{
|
|
genera_movmag(movimenti);
|
|
message_box(TR("Generazione dei movimenti di magazzino terminata"));
|
|
}
|
|
else
|
|
message_box(TR("Non è stato possibile generare nessun documento con i parametri fissati"));
|
|
}
|
|
break;
|
|
default: break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//ELABORA_FILE: metodo che importa il file e prepara la tabella pacchi
|
|
bool TConta_pulito_msk::elabora_file(const TFilename& file)
|
|
{
|
|
if (!file.exist())
|
|
{
|
|
warning_box(TR("ATTENZIONE: il file che si desidera importare non esiste!"));
|
|
return false;
|
|
}
|
|
|
|
TLocalisamfile f(LF_PACCHI);
|
|
TScanner s(file);
|
|
while (s.ok())
|
|
{
|
|
TString riga = s.line();
|
|
if (riga.blank())
|
|
continue;
|
|
|
|
TString80 codpacco = riga.left(50);
|
|
codpacco.trim();
|
|
|
|
TString80 codart = riga.mid(50,20);
|
|
codart.trim();
|
|
|
|
long qta = atoi(riga.mid(70, 8));
|
|
|
|
TDate data(atoi(riga.mid(78, 2)), atoi(riga.mid(80, 2)), atoi(riga.mid(82, 4)));
|
|
|
|
int codcf = atoi(riga.mid(86, 6));
|
|
|
|
const bool ann = riga.mid(100, 1)[0] == 'S' ? true : false;
|
|
|
|
TRiga_pacco* rp = new TRiga_pacco();
|
|
rp->set_key(codpacco);
|
|
rp->set_articolo(codart);
|
|
rp->set_quantita(qta);
|
|
rp->set_data(data);
|
|
|
|
if(codcf > 0)
|
|
{
|
|
rp->set_cliente(codcf); //eventualmente vuoto
|
|
TDate databo(atoi(riga.mid(92, 2)), atoi(riga.mid(94, 2)), atoi(riga.mid(96, 4)));
|
|
rp->set_databo(databo); //eventualmente vuoto
|
|
}
|
|
|
|
rp->set_annullato(ann);
|
|
|
|
//recupero l'unità di misura principale di quest'articolo
|
|
TToken_string key;
|
|
key.add(riga.mid(50, 20));
|
|
key.add(1);
|
|
const TRectype& umart = cache().get(LF_UMART, key);
|
|
if (umart.empty())
|
|
{
|
|
TString str;
|
|
TString80 codart = riga.mid(50,20);
|
|
codart.trim();
|
|
str << "ATTENZIONE: non è stata trovata nessuna unità di misura valida per l'articolo " << codart;
|
|
warning_box(str);
|
|
}
|
|
else
|
|
{
|
|
TString4 um = umart.get(UMART_UM);
|
|
rp->set_um(um);
|
|
}
|
|
|
|
rp->write(f);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//SPOSTA_FILE: metodo che sposta il file elaborato in una sottocartella e gli cambia nome
|
|
//aggiungendo data e ora dell'elaborazione
|
|
void TConta_pulito_msk::sposta_file(const TFilename& file)
|
|
{
|
|
TFilename fileori = file;
|
|
TFilename path = fileori.path();
|
|
path.add("elaborati");
|
|
make_dir(path);
|
|
|
|
TString strname;
|
|
strname.format("%06d_%06d_%s", TDate(TODAY).date2ansi(), daytime(), (const char*)fileori.name());
|
|
TFilename filedest = path;
|
|
filedest.add(strname);
|
|
|
|
if (fcopy(fileori, filedest))
|
|
fileori.fremove();
|
|
}
|
|
|
|
//GENERA_DOCUMENTI: metodo che genera i documenti partendo dal file pacchi
|
|
bool TConta_pulito_msk::genera_documenti(const TFilename& file, TAssoc_array& documenti)
|
|
{
|
|
//se esite un file da importare, lo importo e lo sposto
|
|
if (file.exist())
|
|
{
|
|
elabora_file(file);
|
|
sposta_file(file);
|
|
}
|
|
|
|
TBuoni_cache ca;
|
|
|
|
//inizializzo le variabili di interesse
|
|
TDate dadata(TODAY);
|
|
TDate adata(TODAY);
|
|
long codcf = _codcf;
|
|
|
|
//se non l'ho lanciato da linea di comando, inizializzo le variabili
|
|
//ai dati presi dalla maschera
|
|
if (_auto != 'A')
|
|
{
|
|
dadata = get_date(F_DADATA);
|
|
adata = get_date(F_ADATA);
|
|
codcf = get_long(F_CODCF);
|
|
}
|
|
|
|
//seleziona tutti i record del file pacchi da data a data e eventualmente filtrati per cliente
|
|
//che risultano associati a un cliente ma che non hanno una bolla associata
|
|
TString query;
|
|
query << "USE PACCHI KEY 2\n";
|
|
query << "SELECT (NDOC=0)&&(CODCF>0)&&(MGNUMREG=0)\n";
|
|
query << "FROM DATA=#DADATA";
|
|
if (codcf > 0)
|
|
query << " CODCF=" << codcf;
|
|
query << "\n";
|
|
query << "TO DATA=#ADATA";
|
|
if (codcf > 0)
|
|
query << " CODCF=" << codcf;
|
|
|
|
TISAM_recordset selrighe(query);
|
|
selrighe.set_var("#DADATA", dadata);
|
|
selrighe.set_var("#ADATA", adata);
|
|
|
|
selrighe.move_first();
|
|
TLocalisamfile& pacchi = selrighe.cursor()->file();
|
|
|
|
//scorro tutti i pacchi trovati
|
|
for (bool ok = selrighe.move_first(); ok; ok = selrighe.move_next())
|
|
{
|
|
TRiga_pacco rp = selrighe.cursor()->curr();
|
|
|
|
//se il pacco risulta annullato, lo elimino
|
|
if(rp.is_annullato())
|
|
{
|
|
rp.remove(pacchi);
|
|
continue;
|
|
}
|
|
|
|
//recupero i dati di interesse dal pacco
|
|
const long codcf = rp.cliente();
|
|
const TDate datadoc = rp.databo();
|
|
const TString80 codart = rp.articolo();
|
|
const real quantita = rp.quantita();
|
|
|
|
//instanzio un contratto e la corrispondente riga contratto per l'articolo che sto analizzando
|
|
TLaundry_contract cont(codcf, 0, datadoc);
|
|
const TRectype rcont = cont.row(codart);
|
|
|
|
bool dtmp = false;
|
|
if (datadoc >= rcont.get_date(LVRCONDV_INDTTMP) && datadoc <= rcont.get_date(LVRCONDV_FIDTTMP))
|
|
dtmp = true;
|
|
|
|
//leggo la causale (quella su contratto ha precedenza)
|
|
TString4 causale = rcont.get(LVRCONDV_CAUSLAV);
|
|
if (causale.blank() || atoi(causale) == 0)
|
|
causale = ini_get_string(CONFIG_DITTA, "lv", "CAUSLAV");
|
|
|
|
//leggo se devo scrivere il prezzo sulla bolla
|
|
//const bool prinbo = cont.get_bool(LVCONDV_STPRZBOL);
|
|
const bool prinbo = true; //sempre a true; verrà gestita a video in futuro (27/10/2009)
|
|
|
|
//instanzio una cache sulla tabella del magazzino
|
|
const TRectype& anamag = cache().get(LF_ANAMAG,codart);
|
|
//recupero i dati di interesse dall'anagrafica di magazzino
|
|
const TString80 descr = anamag.get(ANAMAG_DESCR);
|
|
|
|
//recupero i valori delle dotazione temporanea dal magazzino del cliente
|
|
TLocalisamfile magcli(LF_CLIFOGIAC);
|
|
magcli.put(CLIFOGIAC_ANNOES, datadoc.year());
|
|
magcli.put(CLIFOGIAC_TIPOCF, 'C');
|
|
magcli.put(CLIFOGIAC_CODCF, codcf);
|
|
magcli.put(CLIFOGIAC_INDSPED, 0); //in realtà è da leggere dal contratto
|
|
magcli.put(CLIFOGIAC_CODART, codart);
|
|
magcli.put(CLIFOGIAC_NRIGA, 1);
|
|
//leggo il record corrispondente
|
|
magcli.read();
|
|
long dottmp = magcli.get_long(CLIFOGIAC_DOTTM);
|
|
long dotod = magcli.get_long(CLIFOGIAC_DOTOD);
|
|
|
|
//preparo il documento
|
|
TDocumento& doc = ca.doc(datadoc, codcf);
|
|
|
|
//tengo traccia di tutti i documenti che sto generando
|
|
TDoc_key kdoc(doc.get_int(DOC_ANNO), doc.get(DOC_CODNUM), doc.get_int(DOC_NDOC));
|
|
if (!documenti.is_key(kdoc))
|
|
documenti.add(kdoc, kdoc);
|
|
|
|
//azzero coditi e metto dataprco alla datadoc se non sto generando per giri
|
|
if(!_giri || !get_bool(F_GIRI))
|
|
{
|
|
doc.put("DATAPRCO", datadoc);
|
|
doc.put("CODITI", 0);
|
|
}
|
|
|
|
bool found = false;
|
|
//cerco eventualmente una riga documento che contiene già questo articolo;
|
|
//se la trovo sommo le quantità, altrimento preparo una riga nuova
|
|
for (int i = 1; i <= doc.rows(); i++)
|
|
{
|
|
TRiga_documento& rdoc = doc[i];
|
|
|
|
if(codart == rdoc.get(RDOC_CODART))
|
|
{
|
|
rdoc.add(RDOC_QTA, quantita);
|
|
rdoc.add(RDOC_QTAGG1, quantita);
|
|
rdoc.add("DOTOD", quantita);
|
|
if(dtmp)
|
|
rdoc.add("DOTMP", quantita);
|
|
found = true;
|
|
|
|
//scrivo i riferimenti alla bolla sul pacco
|
|
rp.set_rigabolla(datadoc.year(), doc.get(DOC_CODNUM), doc.get_long(DOC_NDOC), i);
|
|
rp.rewrite(pacchi);
|
|
}
|
|
}
|
|
|
|
if(!found)
|
|
{
|
|
TRiga_documento& rdoc = doc.new_row("21");
|
|
rdoc.put(RDOC_CODART, codart);
|
|
rdoc.put(RDOC_CODARTMAG,codart);
|
|
rdoc.put(RDOC_CHECKED,'X');
|
|
rdoc.put(RDOC_GENERATA, true);
|
|
|
|
if(descr.len() <= 50)
|
|
rdoc.put(RDOC_DESCR, descr);
|
|
else
|
|
{
|
|
rdoc.put(RDOC_DESCR, descr.left(50));
|
|
rdoc.put(RDOC_DESCEST, descr.sub(50));
|
|
rdoc.put(RDOC_DESCLUNGA, true);
|
|
}
|
|
|
|
rdoc.put(RDOC_QTA, quantita); //consegnato
|
|
rdoc.put(RDOC_QTAGG1, quantita); //ritirato
|
|
|
|
rdoc.put("DOTOD", dotod);
|
|
rdoc.add("DOTOD", quantita);
|
|
|
|
if(dtmp)
|
|
{
|
|
rdoc.put("DOTMP", dottmp);
|
|
rdoc.add("DOTMP", quantita);
|
|
}
|
|
|
|
rdoc.put(RDOC_CODAGG1, causale);
|
|
|
|
//gestione prezzo
|
|
if (prinbo)
|
|
{
|
|
real prezzo;
|
|
if (cont.get_int(LVCONDV_TIPOLIS) == 0)
|
|
prezzo = rcont.get_real(LVRCONDV_PREZZO);
|
|
else
|
|
prezzo = anamag.get_real(ANAMAG_COSTSTD);
|
|
|
|
rdoc.put(RDOC_PREZZO, prezzo);
|
|
rdoc.put(RDOC_SCONTO,rcont.get(LVRCONDV_SCONTPERC)); //sconto
|
|
}
|
|
|
|
//scrivo il magazzino
|
|
TString8 magazzino;
|
|
TString8 magazzinoc;
|
|
|
|
magazzino << ini_get_string(CONFIG_DITTA, "lv", "CODMAG") << ini_get_string(CONFIG_DITTA, "lv", "CODMAGN");
|
|
magazzinoc << ini_get_string(CONFIG_DITTA, "lv", "CODMAG") << ini_get_string(CONFIG_DITTA, "lv", "CODMAGC");
|
|
|
|
rdoc.put(RDOC_CODMAG, magazzino);
|
|
rdoc.put(RDOC_CODMAGC, magazzinoc);
|
|
|
|
//scrivo i riferimenti alla bolla sul pacco
|
|
rp.set_rigabolla(datadoc.year(), doc.get(DOC_CODNUM), doc.get_long(DOC_NDOC), doc.rows() + 1);
|
|
rp.rewrite(pacchi);
|
|
}
|
|
}
|
|
ca.destroy();
|
|
return true;
|
|
}
|
|
|
|
//PREPARA_MOVIMENTI: questo metodo prepara il TAssoc_array che contiene i movimenti da generare
|
|
void TConta_pulito_msk::prepara_movimenti(const TFilename& file, TAssoc_array& movimenti)
|
|
{
|
|
//se esite un file da importare, lo importo e lo sposto
|
|
if (file.exist())
|
|
{
|
|
elabora_file(file);
|
|
sposta_file(file);
|
|
}
|
|
|
|
//inizializzo le variabili di interesse
|
|
TDate dadata(TODAY);
|
|
TDate adata(TODAY);
|
|
long codcf = _codcf;
|
|
|
|
//se non ho lanciato il programma da linea di comando, leggo i paramtri dalla maschera
|
|
if (_auto != 'A')
|
|
{
|
|
dadata = get_date(F_DADATA);
|
|
adata = get_date(F_ADATA);
|
|
codcf = get_long(F_CODCF);
|
|
}
|
|
|
|
//seleziona tutti i record del file pacchi da data a data che non hanno una bolla associata
|
|
TString query;
|
|
query << "USE PACCHI KEY 2\n";
|
|
query << "SELECT (NDOC=0)&&(CODCF=0)&&(MGNUMREG=0)\n";
|
|
query << "FROM DATA=#DADATA\n";
|
|
query << "TO DATA=#ADATA";
|
|
|
|
TISAM_recordset selrighe(query);
|
|
selrighe.set_var("#DADATA", dadata);
|
|
selrighe.set_var("#ADATA", adata);
|
|
|
|
selrighe.move_first();
|
|
TLocalisamfile& pacchi = selrighe.cursor()->file();
|
|
|
|
//scorro tutti i pacchi trovato
|
|
for (bool ok = selrighe.move_first(); ok; ok = selrighe.move_next())
|
|
{
|
|
TRiga_pacco rp = selrighe.cursor()->curr();
|
|
|
|
//se il pacco risulta annullato, lo elimino
|
|
if(rp.is_annullato())
|
|
{
|
|
rp.remove(pacchi);
|
|
continue;
|
|
}
|
|
|
|
//recupero i dati di interesse dalla riga pacchi
|
|
const real quantita = rp.quantita();
|
|
const TString80 codart = rp.articolo();
|
|
TString8 ansidate;
|
|
ansidate << rp.data().date2ansi();
|
|
|
|
//preparo un TAssoc_array di TAssoc_array;
|
|
//il primo ha per chiave la data (in ansi) e come contenuto un TAssoc_array degli articoli
|
|
//il secondo ha per chiave il codart e come contenuto le quantità
|
|
TAssoc_array* articoli = (TAssoc_array*)movimenti.objptr(ansidate);
|
|
if(articoli == NULL)
|
|
{
|
|
articoli = new TAssoc_array();
|
|
movimenti.add(ansidate, articoli);
|
|
}
|
|
if(articoli->is_key(codart))
|
|
{
|
|
real& qta = *(real*)articoli->objptr(codart);
|
|
qta += quantita;
|
|
}
|
|
else
|
|
articoli->add(codart, quantita);
|
|
}
|
|
}
|
|
|
|
//GENERA_MOVMAG: metodo che genera i movimenti di magazzino dai pacchi
|
|
bool TConta_pulito_msk::genera_movmag(TAssoc_array& movimenti)
|
|
{
|
|
const TCausale_magazzino causale((ini_get_string(CONFIG_DITTA, "lv", "CAUCARMAG")));
|
|
TString8 magazzino;
|
|
magazzino << ini_get_string(CONFIG_DITTA, "lv", "CODMAG") << ini_get_string(CONFIG_DITTA, "lv", "CODMAGP");
|
|
|
|
//cerco l'ultimo numero di chiave in movmag
|
|
TISAM_recordset mov("USE MOVMAG");
|
|
long nummov = 0;
|
|
if(!mov.move_first())
|
|
nummov += mov.get(MOVMAG_NUMREG).as_int();
|
|
|
|
TLocalisamfile movi(LF_MOVMAG);
|
|
|
|
//inizializzo le variabili di interesse
|
|
TDate dadata(TODAY);
|
|
TDate adata(TODAY);
|
|
long codcf = _codcf;
|
|
|
|
//se non ho lanciato il programma da linea di comando, leggo i paramtri dalla maschera
|
|
if (_auto != 'A')
|
|
{
|
|
dadata = get_date(F_DADATA);
|
|
adata = get_date(F_ADATA);
|
|
codcf = get_long(F_CODCF);
|
|
}
|
|
|
|
//per ogni oggetto salvato in movimenti, creo un movimento di magazzino
|
|
FOR_EACH_ASSOC_OBJECT(movimenti, hobj, ansidate, obj)
|
|
{
|
|
TEsercizi_contabili es;
|
|
TDate data = (TDate)ansidate;
|
|
int annoes = es.date2esc(data);
|
|
TMov_mag movmag(++nummov);
|
|
movmag.put(MOVMAG_ANNOES, annoes);
|
|
movmag.put(MOVMAG_DATAREG, data);
|
|
movmag.put(MOVMAG_CODCAUS, causale.codice());
|
|
|
|
//seleziona tutti i record del file pacchi da data a data che non hanno una bolla associata
|
|
//per poter assegnare il riferimento al movimento di magazzino
|
|
TString query;
|
|
query << "USE PACCHI KEY 2\n";
|
|
query << "SELECT (NDOC=0)&&(CODCF=0)&&(MGNUMREG=0)\n";
|
|
query << "FROM DATA=#DADATA\n";
|
|
query << "TO DATA=#ADATA";
|
|
|
|
TISAM_recordset selrighe(query);
|
|
selrighe.set_var("#DADATA", data);
|
|
selrighe.set_var("#ADATA", data);
|
|
|
|
selrighe.move_first();
|
|
TLocalisamfile& pacchi = selrighe.cursor()->file();
|
|
|
|
//scorro tutti i pacchi trovato
|
|
for (bool ok = selrighe.move_first(); ok; ok = selrighe.move_next())
|
|
{
|
|
TRiga_pacco rp = selrighe.cursor()->curr();
|
|
rp.set_movmag(nummov);
|
|
rp.rewrite(pacchi);
|
|
}
|
|
|
|
TAssoc_array& articoli = *(TAssoc_array*)obj;
|
|
|
|
//per ogni articolo contenuto nel secondo TAssoc_array, faccio una riga movimento di magazzino
|
|
FOR_EACH_ASSOC_OBJECT(articoli, hobj1, codart, qta)
|
|
{
|
|
//recupero l'unità di misura principale di quest'articolo
|
|
TToken_string key;
|
|
key.add(codart);
|
|
key.add(1);
|
|
const TRectype& umart = cache().get(LF_UMART, key);
|
|
TString4 um = umart.get(UMART_UM);
|
|
|
|
const real& quantita = *(real*)qta;
|
|
|
|
//faccio la nuova riga del movimento di magazzino
|
|
TRectype& rmovmag = movmag.new_row();
|
|
rmovmag.put(RMOVMAG_CODMAG, magazzino);
|
|
rmovmag.put(RMOVMAG_CODART, codart);
|
|
//rmovmag.put(RMOVMAG_CODCAUS, causale.codice());
|
|
rmovmag.put(RMOVMAG_UM, um);
|
|
rmovmag.put(RMOVMAG_QUANT, quantita);
|
|
}
|
|
movmag.write(movi);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//metodo costruttore che precarica i campi di interesse sulla maschera
|
|
TConta_pulito_msk::TConta_pulito_msk():TAutomask("lv2900a")
|
|
{
|
|
TConfig configlv(CONFIG_DITTA, "lv");
|
|
|
|
const TString& path = configlv.get("PathPulito");
|
|
TFilename& file = (TFilename)configlv.get("FilePulito");
|
|
TString80 f = file.name_only();
|
|
f << ".dat";
|
|
|
|
set(F_PATH, path);
|
|
set(F_FNAME, f);
|
|
|
|
//se ho più di un parametro, allora lo sto lanciando da linea di comando, e ne devo tenere conto
|
|
if (main_app().argc() > 2)
|
|
{
|
|
_auto = main_app().argv(2);
|
|
_auto = _auto.right(1);
|
|
|
|
TString16 tmp = main_app().argv(3);
|
|
if (tmp.left(2) == "-C")
|
|
{
|
|
_percli = true;
|
|
|
|
if (tmp.len() > 2)
|
|
_codcf = atoi(tmp.sub(2));
|
|
else
|
|
_codcf = 0;
|
|
|
|
_permag = false;
|
|
}
|
|
else
|
|
{
|
|
_percli = false;
|
|
_permag = true;
|
|
}
|
|
_giri = main_app().argv(4);
|
|
_giri = _giri.right(1);
|
|
|
|
_print = main_app().argv(5);
|
|
_print = _print.right(1);
|
|
}
|
|
else
|
|
{
|
|
_auto = "N";
|
|
_percli = false;
|
|
_permag = false;
|
|
_codcf = 0;
|
|
_giri = "";
|
|
_print = "";
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////
|
|
//// TCONTA_PULITO_APP ////
|
|
/////////////////////////////////
|
|
|
|
//classe TConta_pulito_app
|
|
class TConta_pulito_app : public TSkeleton_application
|
|
{
|
|
TConta_pulito_msk* _msk;
|
|
TString4 _auto;
|
|
char _cliormag;
|
|
|
|
protected:
|
|
virtual bool create();
|
|
virtual bool destroy();
|
|
|
|
public:
|
|
bool transfer();
|
|
virtual void main_loop();
|
|
};
|
|
|
|
|
|
|
|
//CREATE: metodo costruttore
|
|
bool TConta_pulito_app::create()
|
|
{
|
|
_msk = new TConta_pulito_msk();
|
|
|
|
//se ho più di un parametro, allora lo sto lanciando da linea di comando, e ne devo tenere conto
|
|
if (argc() > 2)
|
|
{
|
|
_auto = argv(2);
|
|
_auto = _auto.right(1);
|
|
|
|
TString16 tmp = argv(3);
|
|
char c = tmp.mid(1,1)[0];
|
|
switch (c)
|
|
{
|
|
case 'C': _cliormag = 'C'; break;
|
|
case 'M': _cliormag = 'M'; break;
|
|
case 'I': _cliormag = 'I'; break;
|
|
default: break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_auto = "";
|
|
_cliormag = ' ';
|
|
}
|
|
|
|
open_files(LF_DOC, LF_RIGHEDOC);
|
|
|
|
return TSkeleton_application::create();
|
|
}
|
|
|
|
//DESTROY: metodo distruttore
|
|
bool TConta_pulito_app::destroy()
|
|
{
|
|
delete _msk;
|
|
return TApplication::destroy();
|
|
}
|
|
|
|
//TRANSFER: metodo che decide cosa effettivamente far fare al programma a seconda delle indicazioni ricevute
|
|
bool TConta_pulito_app::transfer()
|
|
{
|
|
|
|
return true;
|
|
}
|
|
|
|
void TConta_pulito_app::main_loop()
|
|
{
|
|
//lo lancio in automatico da linea di comando
|
|
if (_auto == "A")
|
|
switch(_cliormag)
|
|
{
|
|
case 'C': _msk->send_key(K_SPACE, DLG_PACKTCLI); break;
|
|
case 'M': _msk->send_key(K_SPACE, DLG_PACKTMAG); break;
|
|
case 'I': _msk->send_key(K_SPACE, DLG_IMPORT); break;
|
|
default: break;
|
|
}
|
|
while (_msk->run() == K_ENTER)
|
|
transfer();
|
|
}
|
|
|
|
int lv2900(int argc, char *argv[])
|
|
{
|
|
TConta_pulito_app a;
|
|
a.run (argc, argv, "Elaborazioni pulito");
|
|
return TRUE;
|
|
}
|