campo-sirio/lv/lv2900.cpp
luca83 68c7955e27 Patch level : 10.0 patch ???
Files correlati     : lv2 lv3
Ricompilazione Demo : [ ]
Commento            :
modificato il controllo per riportare su tutti i tipi documento la descrizione estesa degli articoli, ove questa è prevista


git-svn-id: svn://10.65.10.50/branches/R_10_00@20857 c028cbd2-c16b-5b4b-a496-9718f37d4682
2010-09-14 10:47:54 +00:00

1078 lines
32 KiB
C++
Executable File

#include <applicat.h>
#include <automask.h>
#include <defmask.h>
#include <execp.h>
#include <reprint.h>
#include <reputils.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();
TToken_string orderkey;
orderkey.add(RDOC_CODART);
doc.sort_rows(orderkey);
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(0);
const TDate datagen(TODAY);
TDate dadata = datadoc;
TDate adata = datagen;
adata.addmonth();
const long codcf = chiave.get_long();
const TDate datadausare = ini_get_bool(CONFIG_DITTA, "lv", "DataBcon") ? datagen : datadoc;
if(_ndoc == 0)
{
TString query2;
query2 << "USE DOC\n"
<< "FROM PROVV=\"D\" ANNO=" << datadausare.year() << " CODNUM=\"" << _codnum << "\"\n"
<< "TO PROVV=\"D\" ANNO=" << datadausare.year() << " CODNUM=\"" << _codnum << "\"";
TISAM_recordset sporco(query2);
if (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=" << datadausare.year() << " DATADOC=" << datadausare << " CODNUM=" << _codnum << "\n";
query << "TO TIPOCF=C CODCF=" << codcf << " PROVV=D ANNO=" << datadausare.year() << " DATADOC=" << datadausare << " CODNUM=" << _codnum << "\n";
TISAM_recordset rset(query);
TDocumento* doc = NULL;
if (rset.move_first())
doc = new TDocumento(rset.cursor()->curr());
else
{
TToken_string key;
key.add('C');
key.add(codcf);
const int codindsp = atoi(cache().get(LF_CFVEN, key, CFV_CODINDSP));
TLaundry_contract cont(codcf, codindsp, 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();
TString8 codaut = consegne.get(LVRCONSPLAN_CODAUT).as_string().right(5); codaut.trim();
//recupero i dati di interesse dal cliente
const TRectype& clifo = cache().get(LF_CLIFO, key);
const TString4 codpag = clifo.get(CLI_CODPAG);
const long codabi = clifo.get_long(CLI_CODABI);
const long codcab = clifo.get_long(CLI_CODCAB);
const TString80 iban = clifo.get(CLI_IBAN);
//reupero la cuasale di magazzino di testata
const TString16 causmag = cache().get("%TIP", _tipodoc, "S9");
//recupero i dati di interesse dal file CFVEN
const TRectype& cfven = cache().get(LF_CFVEN, key);
const long codabipr = cfven.get_long(CFV_CODABIPR);
const long codcabpr = cfven.get_long(CFV_CODCABPR);
const bool ragdoc = cfven.get_bool(CFV_RAGGDOC);
const TString8 codag1 = cfven.get(CFV_CODAG1);
const TString4 codmez = cfven.get(CFV_CODSPMEZZO);
const TString4 codporto = cfven.get(CFV_CODPORTO);
const TString4 codnote1 = cfven.get(CFV_CODNOTESP1);
const TString4 codnote2 = cfven.get(CFV_CODNOTESP2);
const TString4 codnote = cfven.get(CFV_CODNOTE);
const TString8 codvet1 = cfven.get(CFV_CODVETT1);
const TString8 codvet2 = cfven.get(CFV_CODVETT2);
const TString8 codvet3 = cfven.get(CFV_CODVETT3);
const real speseinc = cfven.get_real(CFV_PERCSPINC);
const TString4 catven = cfven.get(CFV_CATVEN);
const bool addbolli = cfven.get_bool(CFV_ADDBOLLI);
const TString8 codlist = cfven.get(CFV_CODLIST);
const TString4 codzona = cfven.get(CFV_CODZONA);
if(codaut.empty())
codaut = cfven.get(CFV_CODAG);
//gestione sconto
TString sconto;
const char tpgest = ini_get_string(CONFIG_DITTA, "ve", "GESSCO")[0];
switch(tpgest)
{
case 'P': sconto = cfven.get(CFV_SCONTO); break; //Percentuale su anagrafica cliente
case 'T': sconto = cache().get("%SCC", cfven.get(CFV_CODSCC), "S1"); break; //Gestione tabella sconti
case 'A': //Gestione archivio sconti
{
TConfig ditta(CONFIG_DITTA, "ve");
TLocalisamfile sconti(LF_SCONTI);
sconti.put("TIPO", "I");
if(ditta.get_bool("SCOKEY", "ve", 1))
sconti.put("CODCAT", cfven.get(CFV_CATVEN));
TString16 cod;
if(ditta.get_bool("SCOKEY", "ve", 2))
cod.format("%-2s", (const char*)cfven.get(CFV_CODSCC));
else
cod = " ";
if(ditta.get_bool("SCOKEY", "ve", 3))
{
TString8 tmp;
tmp.format("%-2s", (const char*)cfven.get(CFV_CODZONA));
cod << tmp;
}
else
cod << " ";
if(ditta.get_bool("SCOKEY", "ve", 4))
cod << clifo.get(CLI_CODPAG);
sconti.put("CODART", cod);
if (sconti.read() == NOERR)
sconto = sconti.get("SCONTO");
}
case 'N': //sconto non gestito
default: break;
}
if (cont.get(LVCONDV_CODNUM).empty())
{
doc = new TDocumento('D', datadoc.year(), _codnum, ++_ndoc);
doc->put(DOC_TIPODOC, _tipodoc);
}
else
{
doc = new TDocumento('D', datadoc.year(), cont.get(LVCONDV_CODNUM), ++_ndoc);
doc->put(DOC_TIPODOC, cont.get(LVCONDV_TPDOC));
}
doc->put(DOC_STATO, _stato);
if(ini_get_bool(CONFIG_DITTA, "lv", "DataBcon"))
{
doc->put(DOC_DATADOC, datagen);
//modifica 18/03/2010 richiesta da Diana2000 per i clienti che consegnano tutti i giorni
if(ini_get_bool(CONFIG_DITTA, "lv", "ConDom"))
{
TDate datacon(TODAY); ++datacon;
if(datacon.wday() == 7)
++datacon;
doc->put(DOC_DATAPART, datacon);
}
}
else
doc->put(DOC_DATADOC, datadoc);
doc->put(DOC_TIPOCF, 'C');
doc->put(DOC_CODCF, codcf);
doc->put(DOC_CODCONT, codcont);
if(codindsp > 0)
doc->put(DOC_CODINDSP, codindsp);
doc->put(DOC_CODPAG, codpag);
doc->put(DOC_CAUSMAG, causmag);
doc->put(DOC_CODABIA, codabi);
doc->put(DOC_CODCABA, codcab);
doc->put(DOC_IBAN, iban);
doc->put(DOC_CODABIP, codabipr);
doc->put(DOC_CODCABP, codcabpr);
doc->put(DOC_CODAG, codaut);
doc->put(DOC_CODAGVIS, codag1);
doc->put(DOC_CODSPMEZZO, codmez);
doc->put(DOC_ZONA, codzona);
doc->put(DOC_CODPORTO, codporto);
doc->put(DOC_CODNOTESP1, codnote1);
doc->put(DOC_CODNOTESP2, codnote2);
doc->put(DOC_CODNOTE, codnote);
doc->put(DOC_CODVETT1, codvet1);
doc->put(DOC_CODVETT2, codvet2);
doc->put(DOC_CODVETT3, codvet3);
doc->put(DOC_CATVEN, catven);
doc->put(DOC_CODLIST, codlist);
doc->put(DOC_CAUSMAG, causmag);
doc->put(DOC_PERCSPINC, speseinc);
doc->put(DOC_ADDBOLLI, addbolli);
doc->put(DOC_SCONTOPERC, sconto);
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, TLog_report& logrep);
void sposta_file(const TFilename& file);
bool genera_documenti(const TFilename& file, TAssoc_array& documenti, TLog_report& logrep);
void prepara_movimenti(const TFilename& file, TAssoc_array& movimenti, TLog_report& logrep);
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;
TLog_report logrep("");
//a seconda del bottone premuto esegui un metodo diverso
switch (f.dlg())
{
case DLG_IMPORT:
if(e == fe_button)
{
if (elabora_file(file, logrep))
{
sposta_file(file);
if (_auto != "A")
message_box(TR("Importazione dei dati terminata"));
}
}
break;
case DLG_PACKTCLI:
if(e == fe_button)
{
genera_documenti(file, documenti, logrep);
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();
long andoc = 0;
long dandoc = 999999L;
FOR_EACH_ASSOC_OBJECT(documenti, obj, key, itm) \
{
TDoc_key& dk = *(TDoc_key*)itm;
const long ndoc = dk.ndoc();
if (ndoc < dandoc)
dandoc = ndoc;
if (ndoc > andoc)
andoc = ndoc;
}
//lancia la stampa dei documenti ve1 -2 da documento a documento
TString80 str;
str << "ve1 -2 " << codnum << ' ' << anno << ' ' << provv << ' ' << dandoc << '-' << andoc << " S D";
TExternal_app stampa(str);
stampa.run();
}
if (_auto != "A")
message_box(TR("Generazione dei documenti terminata"));
}
else
if (_auto == "A")
logrep.log(2, "Non è stato possibile generare nessun documento con i parametri fissati");
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, logrep);
if (movimenti.items() > 0)
{
genera_movmag(movimenti);
if (_auto != "A")
message_box(TR("Generazione dei movimenti di magazzino terminata"));
}
else
if (_auto == "A")
logrep.log(2, "Non è stato possibile generare nessun movimento di magazzino con i parametri fissati");
else
message_box(TR("Non è stato possibile generare nessun movimento di magazzino con i parametri fissati"));
}
break;
default: break;
}
TReport_book buc;
buc.add(logrep);
//genero il file .log che contiene gli errori
if (buc.pages() > 0)
{
TString str = file.name_only();
str << ".log";
TFilename log = file.path();
log.add(str);
buc.export_text(log, false);
}
if(_auto == "A")
send_key(K_SPACE, DLG_QUIT);
return true;
}
//ELABORA_FILE: metodo che importa il file e prepara la tabella pacchi
bool TConta_pulito_msk::elabora_file(const TFilename& file, TLog_report& logrep)
{
if (!file.exist())
{
if (_auto == "A")
logrep.log(2, "ATTENZIONE: il file che si desidera importare non esiste!");
else
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();
real qta = atoi(riga.mid(70, 8)) / CENTO;
TDate data(atoi(riga.mid(78, 2)), atoi(riga.mid(80, 2)), atoi(riga.mid(82, 4)));
long codcf = atol(riga.mid(86, 6));
const bool ann = riga.mid(100, 1)[0] == 'S' ? true : false;
if(ann)
{
TRiga_pacco rp(codpacco);
rp.set_data(data);
rp.set_annullato(ann);
rp.set_movmag(-1);
rp.rewrite(f);
}
else
{
TRiga_pacco rp;
rp.set_key(codpacco);
rp.set_articolo(codart);
rp.set_quantita(qta);
rp.set_data(data);
if (codcf > 0L)
{
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);
rp.set_movmag(-1);
//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);
if (umart.empty())
{
TString str;
str << "ATTENZIONE: non è stata trovata nessuna unità di misura valida per l'articolo " << codart;
if (_auto == "A")
logrep.log(2, str);
else
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, TLog_report& logrep)
{
//se esite un file da importare, lo importo e lo sposto
if (file.exist())
{
elabora_file(file, logrep);
sposta_file(file);
}
TBuoni_cache ca;
//inizializzo le variabili di interesse
TDate dadata(TODAY); dadata.addyear(-1);
TDate adata(TODAY); adata.addyear();
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);
rp.rewrite(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
TToken_string key;
key.add('C');
key.add(codcf);
const int codindsp = atoi(cache().get(LF_CFVEN, key, CFV_CODINDSP));
TLaundry_contract cont(codcf, codindsp, 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");
const TCausale_lavanderie cau(causale);
const TCausale_magazzino rit(cau.causale_ritiro());
const TCausale_magazzino con(cau.causale_consegna());
//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
TString descr;
descr << anamag.get(ANAMAG_DESCR) << anamag.get(ANAMAG_DESCRAGG);
//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();
real dottmp = magcli.get_real(CLIFOGIAC_DOTTM);
real dotod = magcli.get_real(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);
if(rit.sgn(s_dotod) != 0 || con.sgn(s_dotod) != 0)
{
real qta = (quantita * con.sgn(s_dotod)) - (quantita * rit.sgn(s_dotod));
rdoc.add("DOTOD", qta);
}
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);
if(rit.sgn(s_dotod) != 0 || con.sgn(s_dotod) != 0)
{
real qta = (quantita * con.sgn(s_dotod)) - (quantita * rit.sgn(s_dotod));
rdoc.add("DOTOD", qta);
}
if(dtmp)
rdoc.put("DOTMP", dottmp);
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
const TCausale_lavanderie cau(causale);
TCausale_magazzino rit(cau.causale_ritiro());
TCausale_magazzino con(cau.causale_consegna());
TString8 magazzino;
TString8 magazzinoc;
if(rit.get("S10").full())
magazzino = rit.get("S10").mid(0,5);
else
magazzino << ini_get_string(CONFIG_DITTA, "lv", "CODMAG") << ini_get_string(CONFIG_DITTA, "lv", "CODMAGN");
if(con.get("S10").full())
magazzinoc = con.get("S10").mid(0,5);
else
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);
rdoc.put(RDOC_CODMAG, magazzino);
rdoc.put(RDOC_CODMAGC, magazzinoc);
//recupero l'unità di misura principale di quest'articolo
TToken_string key;
key.add(codart);
key.add(1);
const TString4 um = cache().get(LF_UMART, key, UMART_UM);
rdoc.put(RDOC_UMQTA, um);
//scrivo il codice IVA
const TRectype& anamag = cache().get(LF_ANAMAG, rp.articolo());
rdoc.put(RDOC_CODIVA, anamag.get(ANAMAG_CODIVA));
//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.set_movmag(0);
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, TLog_report& logrep)
{
//se esite un file da importare, lo importo e lo sposto
if (file.exist())
{
elabora_file(file, logrep);
sposta_file(file);
}
//inizializzo le variabili di interesse
TDate dadata(TODAY); dadata.addyear(-1);
TDate adata(TODAY); adata.addyear();
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();
real quantita = rp.quantita();
//se il pacco risulta annullato, storno la quantità
bool annullato = rp.is_annullato();
if(annullato)
quantita = - quantita;
//recupero i dati di interesse dalla riga pacchi
const TString80 codart = rp.articolo();
TToken_string keyarticoli;
keyarticoli.add(codart);
if(annullato)
keyarticoli.add('S');
else
keyarticoli.add('N');
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(keyarticoli))
{
real& qta = *(real*)articoli->objptr(keyarticoli);
qta += quantita;
}
else
articoli->add(keyarticoli, quantita);
//se il pacco risulta annullato, lo elimino
if(annullato)
{
rp.remove(pacchi);
rp.rewrite(pacchi);
}
}
}
//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_last())
nummov += mov.get(MOVMAG_NUMREG).as_int();
TLocalisamfile movi(LF_MOVMAG);
//inizializzo le variabili di interesse
TDate dadata(TODAY); dadata.addyear(-1);
TDate adata(TODAY); adata.addyear();
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());
movmag.put(MOVMAG_DATACOMP, data);
//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 trovati
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, keyarticoli, qta)
{
TToken_string k(keyarticoli);
//recupero l'unità di misura principale di quest'articolo
TToken_string key;
key.add(k.get(0));
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, k.get(0));
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");
//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);
_codcf = 0L;
if (tmp.left(2) == "-C")
{
_percli = true;
if (tmp.len() > 2)
_codcf = atoi(tmp.sub(2));
_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);
file = (TFilename)main_app().argv(6);
}
else
{
_auto = "N";
_percli = false;
_permag = false;
_codcf = 0L;
_giri = "";
_print = "";
}
TString80 f = file.name_only();
f << ".dat";
set(F_PATH, path);
set(F_FNAME, f);
}
/////////////////////////////////
//// 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;
}