cac3c0166b
Files correlati : ps0398 Ricompilazione Demo : [ ] Commento : Migliorate funzioni di log su elaborazione ordini da cartella ftp git-svn-id: svn://10.65.10.50/branches/R_10_00@22367 c028cbd2-c16b-5b4b-a496-9718f37d4682
553 lines
16 KiB
C++
Executable File
553 lines
16 KiB
C++
Executable File
#include <applicat.h>
|
||
#include <automask.h>
|
||
#include <config.h>
|
||
#include <dongle.h>
|
||
#include <execp.h>
|
||
#include <lffiles.h>
|
||
#include <progind.h>
|
||
#include <recarray.h>
|
||
#include <reputils.h>
|
||
#include <textset.h>
|
||
#include <utility.h>
|
||
|
||
#include <doc.h>
|
||
#include <rdoc.h>
|
||
#include "../mg/anamag.h"
|
||
#include "../mg/umart.h"
|
||
|
||
#include "ps0398100a.h"
|
||
|
||
///////////////////////////////////////////////
|
||
// MASCHERA
|
||
///////////////////////////////////////////////
|
||
class TTrasferimento_ordini_mask : public TAutomask
|
||
{
|
||
protected:
|
||
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
|
||
|
||
public:
|
||
TTrasferimento_ordini_mask();
|
||
};
|
||
|
||
TTrasferimento_ordini_mask::TTrasferimento_ordini_mask() : TAutomask("ps0398100a")
|
||
{
|
||
}
|
||
|
||
bool TTrasferimento_ordini_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
||
{
|
||
/*switch(o.dlg())
|
||
{
|
||
default:
|
||
break;
|
||
}*/
|
||
return true;
|
||
}
|
||
|
||
class TTrasferimento_ordini_recordset : public TCSV_recordset
|
||
{
|
||
public:
|
||
TTrasferimento_ordini_recordset(const char* filename);
|
||
};
|
||
|
||
|
||
//////////////////////////////////////////////
|
||
// RECORDSET
|
||
/////////////////////////////////////////////
|
||
//creazione del recordset di ogni ordine
|
||
TTrasferimento_ordini_recordset::TTrasferimento_ordini_recordset(const char* filename) : TCSV_recordset("CSV(\"\t\")")
|
||
{
|
||
load_file(filename);
|
||
};
|
||
|
||
|
||
//////////////////////////////////////////////
|
||
// APPLICAZIONE
|
||
/////////////////////////////////////////////
|
||
//Ridistributore di F24 per il computer
|
||
class TTrasferimento_ordini : public TSkeleton_application
|
||
{
|
||
TTrasferimento_ordini_mask* _mask;
|
||
TString4 _codmag;
|
||
|
||
protected:
|
||
virtual bool check_autorization() const {return false;}
|
||
virtual const char * extra_modules() const {return "ve";}
|
||
virtual bool create();
|
||
virtual void main_loop();
|
||
|
||
public:
|
||
bool ordine_gf(TTrasferimento_ordini_recordset& recset);
|
||
void elab_hd_ht(const TString& riga_txt, const int curr_nriga, TString& str);
|
||
void elab_hf(const TString& riga_txt, const int curr_nriga, TConfig& curr_ini, TLog_report& log, TString& ragsoc);
|
||
void elab_ho(const TString& riga_txt, const int curr_nriga, TConfig& curr_ini, TLog_report& log, TString& ho_note_generali);
|
||
void elab_ra(const TString& riga_txt, const int curr_nriga, TConfig& curr_ini, TLog_report& log);
|
||
bool elabora_file_txt(TTrasferimento_ordini_recordset& recset, const TFilename& ini_fname, TLog_report& log);
|
||
bool sposta_file_elaborato(const TFilename& dst_file, const TFilename& curr_fname, TLog_report& log);
|
||
bool elabora();
|
||
};
|
||
|
||
|
||
//metodo per scoprire se l'ordine <20> di GF o no
|
||
bool TTrasferimento_ordini::ordine_gf(TTrasferimento_ordini_recordset& recset)
|
||
{
|
||
//le righe articolo o sono tutte di GF o non lo sono (nessuna situazione mista)
|
||
bool is_ordine_gf = false;
|
||
|
||
for (bool ok = recset.move_last(); ok; ok = recset.move_prev())
|
||
{
|
||
const TString& riga_txt = recset.get(0L).as_string();
|
||
const TString& tr = riga_txt.left(2);
|
||
if (tr == "RA")
|
||
{
|
||
TToken_string riga_ord(riga_txt.mid(5), ';');
|
||
const TString& codart = riga_ord.get();
|
||
//se il codice articolo non contiene il carattere '.' -> non <20> di GF -> scartato
|
||
const int dot_pos = codart.find('.');
|
||
if (dot_pos >= 0)
|
||
{
|
||
is_ordine_gf = true;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
return is_ordine_gf;
|
||
}
|
||
|
||
void TTrasferimento_ordini::elab_hf(const TString& riga_txt, const int curr_nriga,
|
||
TConfig& curr_ini, TLog_report& log, TString& ragsoc)
|
||
{
|
||
switch (curr_nriga)
|
||
{
|
||
case 1:
|
||
{
|
||
ragsoc = riga_txt.mid(5);
|
||
ragsoc.trim();
|
||
ragsoc.cut(50);
|
||
}
|
||
break;
|
||
case 6:
|
||
{
|
||
const long codcf = atol(riga_txt.mid(14,6));
|
||
//per prima cosa controlla se <20> possibile risalire al cliente che ha generato l'ordine..
|
||
//..no cliente...no party!
|
||
if (codcf <= 0)
|
||
{
|
||
TString msg;
|
||
msg.format("Il cliente %s ha codice nullo!", (const char*)ragsoc);
|
||
log.log(2, msg);
|
||
}
|
||
else
|
||
{
|
||
TString4 head_paragrafo;
|
||
head_paragrafo << LF_DOC;
|
||
curr_ini.set(DOC_TIPOCF, "C", head_paragrafo);
|
||
curr_ini.set(DOC_CODCF, codcf, head_paragrafo);
|
||
}
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
void TTrasferimento_ordini::elab_hd_ht(const TString& riga_txt, const int curr_nriga,
|
||
TString& str)
|
||
{
|
||
if (riga_txt.full())
|
||
{
|
||
switch (curr_nriga)
|
||
{
|
||
case 3:
|
||
case 4:
|
||
str << riga_txt;
|
||
str.strip_double_spaces();
|
||
str << "\\n";
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
void TTrasferimento_ordini::elab_ho(const TString& riga_txt, const int curr_nriga,
|
||
TConfig& curr_ini, TLog_report& log, TString& ho_note_generali)
|
||
{
|
||
switch (curr_nriga)
|
||
{
|
||
case 1: //numero ordine del sito web (per ora non serve, ma poi si vedr<64>...)
|
||
{
|
||
const long num_ord_web = atol(riga_txt.mid(5));
|
||
}
|
||
break;
|
||
case 3: //datadoc (scritta alla cazzo)
|
||
{
|
||
TToken_string str_data(riga_txt.mid(5, 100).before(' '), '/');
|
||
const TDate datadoc(str_data.get_int(0), str_data.get_int(1), str_data.get_int(2));
|
||
if (!datadoc.ok())
|
||
{
|
||
TString msg;
|
||
msg.format(FR("Data documento non valida: %s"), (const char*)str_data);
|
||
log.log(2, msg);
|
||
}
|
||
TString4 head_paragrafo;
|
||
head_paragrafo << LF_DOC;
|
||
curr_ini.set(DOC_DATADOC, datadoc, head_paragrafo);
|
||
}
|
||
break;
|
||
case 4: //altre note ordine (da mettere in DOC_NOTE)
|
||
{
|
||
ho_note_generali << riga_txt.mid(5);
|
||
ho_note_generali.trim();
|
||
}
|
||
break;
|
||
case 5: //codice condizione pagamento (anche questo x ora non serve, ma sempre si vedr<64>...)
|
||
{
|
||
const int cod_pag = atoi(riga_txt.mid(5));
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
} //switch(curr_nriga)
|
||
}
|
||
|
||
|
||
void TTrasferimento_ordini::elab_ra(const TString& riga_txt, const int curr_nriga,
|
||
TConfig& curr_ini, TLog_report& log)
|
||
{
|
||
TToken_string riga_ord(riga_txt.mid(5), ';');
|
||
const TString codart = riga_ord.get();
|
||
TString16 str_qta = riga_ord.get();
|
||
str_qta.strip(". ");
|
||
str_qta.replace(',', '.');
|
||
|
||
//set_paragraph sulle righe (file 34, righedoc)
|
||
TString8 row_paragrafo;
|
||
row_paragrafo << LF_RIGHEDOC << ',' << curr_nriga;
|
||
curr_ini.set_paragraph(row_paragrafo);
|
||
|
||
curr_ini.set(RDOC_TIPORIGA, "01");
|
||
//l'articolo deve esistere per stare in codartmag e codart;
|
||
//se non esiste in anagrafica -> solo in codart con segnalazione
|
||
//la desc riga sar<61> la desc articolo
|
||
const TRectype& rec_anamag = cache().get(LF_ANAMAG, codart);
|
||
//se il record <20> vuoto l'articolo non <20> in anagrafica
|
||
if (rec_anamag.empty())
|
||
{
|
||
TString msg;
|
||
msg = TR("Articolo non in anagrafica");
|
||
curr_ini.set(RDOC_DESCR, msg);
|
||
|
||
msg << ": " << codart;
|
||
log.log(2, msg);
|
||
}
|
||
else //senn<6E> va tranquillo
|
||
{
|
||
// curr_ini.set(RDOC_CODARTMAG, codart);
|
||
curr_ini.set(RDOC_DESCR, rec_anamag.get(ANAMAG_DESCR));
|
||
// curr_ini.set(RDOC_CHECKED, "X");
|
||
|
||
//alla qta associa la prima unit<69> di misura
|
||
TToken_string key_umart;
|
||
key_umart.add(codart);
|
||
key_umart.add(1);
|
||
const TRectype& rec_umart = cache().get(LF_UMART, key_umart);
|
||
const TString& umqta = rec_umart.get(UMART_UM);
|
||
curr_ini.set(RDOC_UMQTA, umqta);
|
||
}
|
||
//queste le fa in ogni modo (forse rischiando)
|
||
curr_ini.set(RDOC_CODART, codart);
|
||
curr_ini.set(RDOC_QTA, str_qta);
|
||
|
||
// TString80 str_prezzo = riga_ord.get(); //per adesso ci si mette il prezzo sull'ordine
|
||
// str_prezzo.replace(',', '.');
|
||
// curr_ini.set(RDOC_PREZZO, str_prezzo);
|
||
//e per ultime le eventuali note
|
||
const TString nota = riga_ord.get();
|
||
if (nota.full())
|
||
{
|
||
curr_ini.set(RDOC_DESCLUNGA, "X");
|
||
curr_ini.set(RDOC_DESCEST, nota);
|
||
}
|
||
|
||
//anzi, per ultimissimo il magazzino
|
||
curr_ini.set(RDOC_CODMAG, _codmag);
|
||
}
|
||
|
||
|
||
bool TTrasferimento_ordini::elabora_file_txt(TTrasferimento_ordini_recordset& recset, const TFilename& ini_fname,
|
||
TLog_report& log)
|
||
{
|
||
//variabili da riempire ad ogni giro
|
||
TString4 curr_tiporiga; //tipo riga in esame (HT...RA), ovvero sezione del file
|
||
int curr_nriga = 0; //n riga della sezione in esame
|
||
TString ragsoc, piva;
|
||
TString hd_spedizione; //questi stanno qui perch<63> valgono una volta per file .txt
|
||
TString ht_fatturazione;
|
||
TString ho_note_generali;
|
||
|
||
//creazione del file .ini di transazione
|
||
TConfig curr_ini(ini_fname);
|
||
|
||
curr_ini.set_paragraph("Transaction"); //setto il paragrafo [Transaction] del file ini
|
||
curr_ini.set("Action","INSERT");
|
||
curr_ini.set("Mode","");
|
||
|
||
//set_paragraph sulle testate (file 33, doc)
|
||
TString4 head_paragrafo;
|
||
head_paragrafo << LF_DOC;
|
||
curr_ini.set_paragraph(head_paragrafo);
|
||
|
||
TToken_string tipi_record("HF|HD|HT|HS|HO|RA");
|
||
|
||
//comincia il giro sulle righe del recordset
|
||
//va al contrario perch<63> se le righe non hanno articoli di GF -> salta il tutto
|
||
for (bool ok = recset.move_first(); ok; ok = recset.move_next())
|
||
{
|
||
//riga corrente del file di input
|
||
const TString& riga_txt = recset.get(0L).as_string();
|
||
|
||
//gestione cambio riga e cambio sezione
|
||
const TString& tr = riga_txt.left(2);
|
||
if (tipi_record.get_pos(tr) < 0)
|
||
{
|
||
if (curr_tiporiga == "HO")
|
||
{
|
||
//righe del cazzo senza capo; in teoria possono appartenere solo al campo NOTE di HO (in teoria, ovviamente)
|
||
TString riga_del_cazzo = riga_txt;
|
||
riga_del_cazzo.trim();
|
||
ho_note_generali << " " << riga_del_cazzo;
|
||
}
|
||
continue;
|
||
}
|
||
|
||
if (tr != curr_tiporiga)
|
||
{
|
||
curr_tiporiga = tr;
|
||
curr_nriga = 1;
|
||
}
|
||
else
|
||
curr_nriga ++;
|
||
|
||
//trattazione delle varie sezioni
|
||
// HS (va saltata)
|
||
if (curr_tiporiga == "HS")
|
||
continue;
|
||
|
||
// HF
|
||
if (curr_tiporiga == "HF")
|
||
elab_hf(riga_txt, curr_nriga, curr_ini, log, ragsoc);
|
||
|
||
// HD
|
||
if (curr_tiporiga == "HD")
|
||
elab_hd_ht(riga_txt.mid(5, 100), curr_nriga, hd_spedizione); //(note spedizione)
|
||
|
||
// HT
|
||
if (curr_tiporiga == "HT")
|
||
elab_hd_ht(riga_txt.mid(5, 100), curr_nriga, ht_fatturazione); //(note fatturazione)
|
||
|
||
// HO
|
||
if (curr_tiporiga == "HO")
|
||
elab_ho(riga_txt, curr_nriga, curr_ini, log, ho_note_generali);
|
||
|
||
// RA
|
||
//gestione delle righe ordine
|
||
if (curr_tiporiga == "RA")
|
||
elab_ra(riga_txt, curr_nriga, curr_ini, log);
|
||
|
||
} //for(bool ok=recset.move.frst...
|
||
|
||
//scrive sul campo NOTE della testata quello che sa delle note spedizione e fatturazione
|
||
TString note;
|
||
note << '"';
|
||
|
||
if (hd_spedizione.full())
|
||
note << "Note Spedizione: " << hd_spedizione << "\\n";
|
||
if (ht_fatturazione.full())
|
||
note << "Note Fatturazione: " << ht_fatturazione << "\\n";
|
||
if (ho_note_generali.full())
|
||
note << "Note generali: " << ho_note_generali;
|
||
|
||
note << '"';
|
||
curr_ini.set(DOC_NOTE, note, head_paragrafo);
|
||
|
||
//qui ci va il lancio di ve0 con l'ini generato
|
||
curr_ini.set(DOC_PROVV, "D");
|
||
curr_ini.set(DOC_CODNUM, _mask->get(F_CODNUM));
|
||
const TDate datadoc = curr_ini.get(DOC_DATADOC);
|
||
curr_ini.set(DOC_ANNO, datadoc.year());
|
||
curr_ini.set(DOC_TIPODOC, _mask->get(F_TIPODOC));
|
||
curr_ini.set(DOC_STATO, 1);
|
||
|
||
return true;
|
||
}
|
||
|
||
bool TTrasferimento_ordini::sposta_file_elaborato(const TFilename& dst_file, const TFilename& curr_fname,
|
||
TLog_report& log)
|
||
{
|
||
bool copia_riuscita = fcopy(curr_fname, dst_file, false, true);
|
||
if (copia_riuscita)
|
||
{
|
||
const long src_size = fsize(curr_fname);
|
||
const long dst_size = fsize(dst_file);
|
||
|
||
copia_riuscita = src_size == dst_size;
|
||
}
|
||
if (copia_riuscita) //se va tutto bene elimina il file dalla directory di origine
|
||
{
|
||
#ifdef DBG
|
||
if (noyes_box(FR("Si desidera eliminare il file remoto '%s'"), (const char*)curr_fname))
|
||
#endif
|
||
if (!remove_file(curr_fname))
|
||
{
|
||
TString msg;
|
||
msg.format("Impossibile eliminare il file origine '%s'", (const char*)curr_fname);
|
||
log.log(1, msg);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
TString msg;
|
||
msg.format(FR("Impossibile copiare il file '%s'!"), curr_fname.name());
|
||
log.log(2, msg);
|
||
}
|
||
return copia_riuscita;
|
||
}
|
||
|
||
|
||
bool TTrasferimento_ordini::elabora()
|
||
{
|
||
TFilename src_files = _mask->get(F_PATH_SRC);
|
||
src_files.add("*HEADER.txt");
|
||
TString_array src_files_list;
|
||
//dalla cartella origine prende tutti i files *HEADER.txt e crea una simpatica lista
|
||
int n_files_txt = 0;
|
||
if (src_files.full())
|
||
{
|
||
TWait_cursor hourglass;
|
||
n_files_txt = list_files(src_files, src_files_list);
|
||
}
|
||
|
||
//gi<67> che c'<27> prende pure gli altri dati dalla maschera che gli servono poi
|
||
TFilename dst_path = _mask->get(F_PATH_DST);
|
||
|
||
//cartella dove saranno creati i .ini
|
||
TFilename tmp;
|
||
tmp.tempdir();
|
||
tmp.add("ps0398");
|
||
const bool crea_dir = make_dir(tmp);
|
||
//non riesce a crearla! deve dare errore di grave livello!
|
||
if (!crea_dir)
|
||
{
|
||
TString msg;
|
||
msg.format(FR("Impossibile creare la cartella di lavoro %s!"), tmp);
|
||
return error_box(msg);
|
||
}
|
||
|
||
//scansione dello string_array per il trasferimento (con tanto di progind e log)
|
||
TProgind pi(n_files_txt, main_app().title(), true, true);
|
||
|
||
TLog_report log(main_app().title());
|
||
if (n_files_txt >= 0)
|
||
{
|
||
const bool pasv = ini_get_string(CONFIG_INSTALL, "Server", "ftp", "Passive")[0] != 'A';
|
||
TString msg;
|
||
msg << src_files;
|
||
log.log(0, msg);
|
||
|
||
msg.cut(0) << n_files_txt << ' ' << TR("ordini da elaborare") << " (ftp " << (pasv ? "Passive" : "Active") << " mode)";
|
||
log.log(n_files_txt<=0 ? 1 : 0, msg);
|
||
}
|
||
|
||
//si accatta anche il magazzino
|
||
_codmag = _mask->get(F_CODMAG);
|
||
|
||
//ciclo su tutti i files .txt da esaminare
|
||
for (int i = 0; i < n_files_txt; i++)
|
||
{
|
||
if (!pi.addstatus(1))
|
||
break;
|
||
|
||
//file in formato filename (<28> l'ordine corrente da elaborare)
|
||
const TFilename curr_fname = src_files_list.row(i);
|
||
TFilename tempfile(tmp);
|
||
tempfile.add(curr_fname.name());
|
||
if (!fcopy(curr_fname, tempfile, false, true))
|
||
{
|
||
TString msg;
|
||
msg << TR("Impossibile leggere il file ") << curr_fname;
|
||
log.log(2, msg);
|
||
continue;
|
||
}
|
||
//creazione del recordset associato al file
|
||
TTrasferimento_ordini_recordset recset(tempfile);
|
||
|
||
//se il file non <20> di GF (si vede dal codart) viene saltato! Hop!
|
||
if (!ordine_gf(recset))
|
||
{
|
||
TString msg;
|
||
msg << TR("File Scartato: ") << curr_fname;
|
||
log.log(1, msg);
|
||
continue;
|
||
}
|
||
|
||
//avverte sul log quale file sta elaborando
|
||
TString msg;
|
||
msg << TR("Elaborazione file ") << curr_fname;
|
||
log.log(0, msg);
|
||
|
||
//per ogni ordine in formato .txt genera un file.ini che andr<64> poi documentizzato
|
||
//file .ini
|
||
TFilename ini_fname = tmp;
|
||
ini_fname.add(format("ORD%05ld.ini", i));
|
||
//elaborazione del file .txt per riempireil .ini della successiva elaborazione differita
|
||
bool elaborazione_ok = elabora_file_txt(recset, ini_fname, log);
|
||
|
||
//elaborazione interattiva dell'ordine dal .ini
|
||
if (elaborazione_ok)
|
||
{
|
||
TString commandline;
|
||
commandline << "ve0 -0 /i" << ini_fname;
|
||
TExternal_app ve(commandline);
|
||
ve.run();
|
||
}
|
||
|
||
//qui ci va lo spostamento del file elaborato se ve0 ha funzionato correttamente
|
||
TFilename dst_file = dst_path;
|
||
dst_file.add(curr_fname.name());
|
||
const bool copia_riuscita = sposta_file_elaborato(dst_file, curr_fname, log);
|
||
} //for(int i...
|
||
|
||
log.log(0, TR("Acquisizione ordini completata"));
|
||
log.preview();
|
||
|
||
return true;
|
||
}
|
||
|
||
bool TTrasferimento_ordini::create()
|
||
{
|
||
Tdninst dninst;
|
||
if (!dninst.can_I_run(true))
|
||
return error_box(TR("Programma non autorizzato!"));
|
||
return TSkeleton_application::create();
|
||
}
|
||
|
||
void TTrasferimento_ordini::main_loop()
|
||
{
|
||
_mask = new TTrasferimento_ordini_mask;
|
||
if (_mask->run() != K_QUIT)
|
||
elabora();
|
||
|
||
delete _mask;
|
||
_mask = NULL;
|
||
}
|
||
|
||
int ps0398100 (int argc, char **argv)
|
||
{
|
||
TTrasferimento_ordini a;
|
||
a.run(argc,argv, TR("Acquisizione ordini web"));
|
||
return true;
|
||
}
|