Patch level :10.0

Files correlati     :
Ricompilazione Demo : [ ]
Commento            :
programma personalizzato di dinamica per importare movana da .csv con le sole righe


git-svn-id: svn://10.65.10.50/trunk@20245 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
luca 2010-03-19 14:24:00 +00:00
parent 935f8e8f91
commit 85e802a435
6 changed files with 628 additions and 4 deletions

View File

@ -84,8 +84,11 @@ Esportazione bolle Conad per Marpesca (ex ve7400, Marpesca)
Trasferimento JBI (ex ve7600)
Importazione da Galileo Cantieri (ex ve7700)
PS0099
Statistiche ANIVAL
PS0099 ANIVAL
Statistiche di tutti i tipi (cliente/articolo/grmerc)
PS0398 Gianni Ferrari
Acquisizione di .txt generati da e-commerce e conseguente generazione di ordini su Campo.
PS0544 Varauto
Trasferimento a SISIPHO
@ -119,8 +122,8 @@ Stampa ordini di produzione DBService
Aggiornamento IVA Documenti DBService
Pianificazione impianti DBService
PS0925
Cosea esportazione estratti conti su piu' ditte
PS0925 COSEA
Esportazione estratti conti su piu' ditte
PS0982 ACQUACONTROL (GEISOFT)
Importazione CLIFO e ANAMAG per Acquacontrol
@ -142,3 +145,5 @@ Incasso fatture
PT0195 Cucchetto (Prassi Triveneto)
Importazione documenti Volvo
PT1950 Pescatori delta padano (Prassi Triveneto)

16
ps/ps1001.cpp Executable file
View File

@ -0,0 +1,16 @@
#include <xvt.h>
#include "ps1001.h"
int main(int argc, char** argv)
{
int n = argc > 1 ? atoi(argv[1]+1) : 0;
switch(n)
{
case 0: ps1001100(argc, argv); break; //Importazione movimento di analitica da righe in *.csv (DINAMICA)
default:
ps1001100(argc, argv); break;
}
exit(0);
return 0;
}

1
ps/ps1001.h Executable file
View File

@ -0,0 +1 @@
int ps1001100(int argc, char* argv[]);

417
ps/ps1001100.cpp Executable file
View File

@ -0,0 +1,417 @@
#include <applicat.h>
#include <automask.h>
#include <progind.h>
#include <reputils.h>
#include <relation.h>
#include <textset.h>
#include <utility.h>
#include "../ca/calib01.h"
#include "../ca/movana.h"
#include "../ca/rmovana.h"
#include "../cg/cglib01.h"
#include "ps1001.h"
#include "ps1001100a.h"
///////////////////////////////////////////////////////////
// TAutomask
///////////////////////////////////////////////////////////
class TImporta_movana_mask : public TAutomask
{
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
public:
TImporta_movana_mask();
};
TImporta_movana_mask::TImporta_movana_mask() :TAutomask ("ps1001100a")
{
}
bool TImporta_movana_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
{
//giochetto per avere la lista dei files validi nella directory di trasferimento!
case F_NAME:
if (e == fe_button)
{
TArray_sheet as(-1, -1, 72, 20, TR("Selezione file"), "File@32");
TFilename path = get(F_PATH);
path.add("*.csv"); //files delle testate
list_files(path, as.rows_array());
TFilename name;
FOR_EACH_ARRAY_ROW(as.rows_array(), i, row)
{
name = *row;
*row = name.name();
}
if (as.run() == K_ENTER)
{
o.set(as.row(as.selected()));
}
}
break;
//controlli sui campi della testata documento
case F_DATAREG:
if ((e == fe_modify || e == fe_close) && !query_mode())
{
const TDate datareg = o.get();
const TEsercizi_contabili ec;
if (ec.date2esc(datareg) <= 0)
return error_box(((TEdit_field&)o).get_warning());
if (e == fe_close && field(F_DATACOMP).empty())
set(F_DATACOMP, datareg);
}
break;
case F_DATACOMP:
if ((e == fe_modify || e == fe_close) && !query_mode())
{
const TDate datareg = get(F_DATAREG);
TDate datacomp = o.get();
if (!datacomp.ok())
datacomp = datareg;
const bool preventivo = get(F_TIPO).full();
//i movimenti normali devono avere data competenza nel presente o passato!!
if (!preventivo && datacomp > datareg)
return error_box(TR("La data di competenza non puo' superare la data di registrazione"));
const TEsercizi_contabili ec;
int ae = ec.date2esc(datacomp);
//movimenti preventivi in esercizi futuri
if (ae <= 0 && preventivo && datacomp > datareg)
ae = ec.date2esc(datareg) + datacomp.year() - datareg.year();
if (ae > 0)
set(F_ANNOES, ae, 0x1);
else
return error_box(((TEdit_field&)o).get_warning());
const int ar = ec.date2esc(datareg);
const int ap = ec.pred(ar);
//preventivi un anno indietro, nel presente o nel futuro
if (preventivo)
{
if (ae < ap)
return error_box(FR("La data di competenza non può precedere l'esercizio %d"), ap);
}
else //normali solo un anno indietro o nel presente
{
if (ae != ar && ae != ap)
return error_box(FR("La data di competenza deve appartenere all'esercizio in corso o al precedente"));
}
}
break;
case F_DATAFCOMP:
if (e == fe_modify || e == fe_close)
{
const TDate datacomp = get(F_DATACOMP);
const TDate datafcomp = o.get();
if (datafcomp.ok())
{
if (datafcomp < datacomp)
return error_box(((TEdit_field&)o).get_warning());
}
else
o.set(datacomp.string()); //se la data fine competenza viene lasciata vuota -> e' uguale alla datacomp
}
break;
default:
break;
}
return true;
}
/////////////////////////////////////////////////////////////
// Recordset specifici per i dati da trasferire
/////////////////////////////////////////////////////////////
class TImporta_movana_recordset : public TCSV_recordset
{
char _sep_field;
protected:
virtual TRecnotype new_rec(const char* buf = NULL);
public:
TImporta_movana_recordset(const char * fileName, char sep);
};
TRecnotype TImporta_movana_recordset::new_rec(const char* buf)
{
TToken_string str(256,'\t'); //nuovo record tab separator
if(buf && *buf)
{
bool apici = false;
for (const char* c = buf; *c ; c++)
{
if (*c == '"')
{
apici = !apici;
}
else
{
if (*c == _sep_field) //tipo di separatore dei campi che si trova nel record di origine
{
if (!apici)
str << str.separator();
else
str << *c;
}
else
str << *c;
}
}
}
const TRecnotype n = TText_recordset::new_rec(str);
if (n >= 0)
row(n).separator(str.separator());
return n;
}
TImporta_movana_recordset::TImporta_movana_recordset(const char * filename, char sep_field)
: TCSV_recordset("CSV(;)"), _sep_field(sep_field) //separatore campi
{
TString query;
query << "CSV(" << sep_field << ")\n"
<< "SELECT * FROM " << filename;
TFilename n;
if (parse_query(query, n) == _qt_select && n.exist())
load_file(n);
}
///////////////////////////////////////
// TSkeleton_application
///////////////////////////////////////
class TImporta_movana : public TSkeleton_application
{
virtual bool check_autorization() const { return false; }
virtual const char * extra_modules() const { return "ca"; }
TImporta_movana_mask* _msk;
protected:
public:
virtual bool create();
virtual bool destroy();
virtual void main_loop();
bool transfer(const TFilename& file);
TImporta_movana() {};
};
bool TImporta_movana::transfer(const TFilename& file)
{
//roba dalla maschera
const char sep_field = _msk->get(F_SEP_FIELD)[0]; //separatore dei campi
const char sep_dec = _msk->get(F_SEP_DEC)[0]; //separatore decimali
const int annoes = _msk->get_int(F_ANNOES);
const TDate datareg = _msk->get_date(F_DATAREG);
const TDate datacomp = _msk->get_date(F_DATACOMP);
const TDate datafcomp = _msk->get_date(F_DATAFCOMP);
const bool autofcomp = _msk->get_bool(F_AUTOFCOMP);
const TString descrizione = _msk->get(F_DESCR);
const char tipomov = _msk->get(F_TIPO)[0];
const TString4 codcaus = _msk->get(F_CODCAUS);
//crea il recordset sul file di input utilizzando il separatore
TImporta_movana_recordset s(file, sep_field);
const long recset_items = s.items();
//un po' di roba iniziale
TProgind pi(s.items(),"Importazione movimento in corso ...",true,true);
TLog_report log("ERRORI DI TRASFERIMENTO");
int curr_line = 0;
//testata
//-------
//movimento analitico che sarà generato
TAnal_mov movana;
movana.put(MOVANA_DATAREG, datareg);
movana.put(MOVANA_DATACOMP, datacomp);
movana.put(MOVANA_DATAFCOMP, datafcomp);
movana.put(MOVANA_ANNOES, annoes);
movana.put(MOVANA_DESCR, descrizione);
movana.put(MOVANA_TIPOMOV, tipomov);
movana.put(MOVANA_CODCAUS, codcaus);
movana.put(MOVANA_AUTOFCOMP, autofcomp);
TImporto totale;
//giro su tutti i record del recordset per importarli; ogni record è una riga
//righe analitiche
//----------------
for (bool ok = s.move_first(); ok; ok = s.move_next())
{
if (!pi.addstatus(1))
break;
curr_line ++;
//nuova riga del movana (sfrutta il fatto che è un multiple rectype)
TRectype& rmovana = movana.new_row();
//prende i dati dal record di input del file csv
//----------------------------------------------
//codcms ci deve essere e va maiuscolizzato; se non c'è va segnalato sul log..
//..ed impedirà la write del movana
TString80 codcms = s.get(0).as_string();
if (codcms.blank())
{
TString msg;
msg.format("Manca la commessa nella riga %ld", curr_line);
log.log(2, msg);
continue;
}
codcms.upper();
//cdc ci deve essere e va maiuscolizzato; se non c'è va segnalato sul log..
//..ed impedirà la write del movana
TString80 cdc = s.get(1).as_string();
if (cdc.blank())
{
TString msg;
msg.format("Manca la sede nella riga %ld", curr_line);
log.log(2, msg);
continue;
}
cdc.upper();
//importo (inizialmente come stringa x poter fare le replace); se nullo va segnalato..
//..ma niente bloccaggio della write
TString80 str_importo = s.get(2).as_string();
if (sep_dec == ',')
{
str_importo.replace('.',' '); //togle il separatore delle migliaia
str_importo.replace(',','.'); //sostituisce il separatore decimale
}
else
str_importo.replace(',',' '); //togle il separatore delle migliaia
str_importo.strip_spaces();
str_importo.trim();
const real importo = str_importo;
/*if (importo == ZERO)
{
TString msg;
msg.format("Importo nullo nella riga %ld", curr_line);
log.log(0, msg);
}*/
//sezione
TString8 str_sezione = s.get(3).as_string();
if (str_sezione.blank())
{
TString msg;
msg.format("Manca la sezione nella riga %ld", curr_line);
log.log(2, msg);
continue;
}
str_sezione.upper();
const char sezione = str_sezione[0];
//conto
const int gr = s.get(4).as_int();
const int co = s.get(5).as_int();
const long so = s.get(6).as_int();
TString80 conto;
conto.format("%03d%03d%06ld", gr, co, so);
if (conto.blank())
{
TString msg;
msg.format("Manca il conto nella riga %ld", curr_line);
log.log(2, msg);
continue;
}
//riempie la riga analitica
//-------------------------
rmovana.put(RMOVANA_DESCR, "Riga importata");
rmovana.put(RMOVANA_CODCONTO, conto);
rmovana.put(RMOVANA_CODCMS, codcms);
rmovana.put(RMOVANA_CODCCOSTO, cdc);
rmovana.put(RMOVANA_SEZIONE, sezione);
rmovana.put(RMOVANA_IMPORTO, importo);
//aggiorna anche il totale documento
TImporto importo_riga(sezione, importo);
totale += importo_riga;
}
//completa la testata
//-------------------
totale.normalize();
movana.put(MOVANA_SEZIONE, totale.sezione());
movana.put(MOVANA_TOTDOC, totale.valore());
//solo se non ci sono errori procede alla registrazione del movimento
const int items = log.recordset()->items();
if (items > 1)
log.preview();
else
{
TLocalisamfile fmovana(LF_MOVANA);
int err = movana.rewrite_write(fmovana);
if (err != NOERR)
error_box("Impossibile registrare il movimento analitico generato!");
}
return true;
}
bool TImporta_movana::create()
{
_msk = new TImporta_movana_mask();
return TSkeleton_application::create();
}
bool TImporta_movana::destroy()
{
delete _msk;
return TApplication::destroy();
}
void TImporta_movana::main_loop()
{
KEY tasto;
tasto = _msk->run();
TConfig& cfg = ca_config();
const bool use_pdcc = cfg.get_bool("UsePdcc");
if (use_pdcc)
{
if (tasto == K_ENTER)
{
//genero il nome del file da caricare
TFilename name = _msk->get(F_PATH);
name.add(_msk->get(F_NAME));
if (transfer(name))
{
message_box(TR("Elaborazione completata"));
}
}
}
else
error_box("Il programma richiede che sia impostato l'uso del piano dei conti contabile in analitica!");
}
TImporta_movana& app() { return (TImporta_movana&) main_app(); }
int ps1001100 (int argc, char* argv[])
{
TImporta_movana main_app;
main_app.run(argc, argv, TR("Importazione movimento analitico da CSV"));
return true;
}

16
ps/ps1001100a.h Executable file
View File

@ -0,0 +1,16 @@
#define F_CODITTA 101
#define F_RAGSOC 102
#define F_PATH 103
#define F_NAME 104
#define F_SEP_FIELD 105
#define F_SEP_DEC 106
#define F_TIPO 110
#define F_DATAREG 111
#define F_ANNOES 112
#define F_DATACOMP 113
#define F_DATAFCOMP 114
#define F_AUTOFCOMP 115
#define F_DESCR 116
#define F_CODCAUS 117
#define F_DESCAUS 118

169
ps/ps1001100a.uml Executable file
View File

@ -0,0 +1,169 @@
#include "ps1001100a.h"
TOOLBAR "" 0 0 0 2
#include <elabar.h>
ENDPAGE
PAGE "Importazione movimento analitico " 0 2 0 0
GROUPBOX DLG_NULL 78 6
BEGIN
PROMPT 1 1 "@bParametri importazione"
END
STRING F_PATH 255 48
BEGIN
PROMPT 2 2 "Cartella origine dati "
FLAGS "M"
DSELECT
CHECKTYPE REQUIRED
END
STRING F_NAME 60 48
BEGIN
PROMPT 2 3 "File da importare (*.csv) "
FLAGS "B"
CHECKTYPE REQUIRED
END
STRING F_SEP_FIELD 1
BEGIN
PROMPT 2 4 "Separatore dei campi nel file .csv "
CHECKTYPE REQUIRED
END
STRING F_SEP_DEC 1
BEGIN
PROMPT 2 5 "Separatore decimale nel file .csv "
CHECKTYPE REQUIRED
END
GROUPBOX DLG_NULL 78 10
BEGIN
PROMPT 1 7 "@bParametri testata movimento"
END
LIST F_TIPO 1 25
BEGIN
PROMPT 2 8 "Tipo movimento "
ITEM " |Normale"
ITEM "P|Preventivo"
ITEM "V|Variazione preventivo"
END
DATE F_DATAREG
BEGIN
PROMPT 2 9 "Data di registrazione "
CHECKTYPE REQUIRED
FLAGS "A"
WARNING "La data di registrazione non appartiene ad un esercizio valido"
END
NUMBER F_ANNOES 4
BEGIN
PROMPT 54 9 "Esercizio "
FLAGS "DG"
END
DATE F_DATACOMP
BEGIN
PROMPT 2 10 "Data di competenza "
CHECKTYPE REQUIRED
WARNING "La data di competenza non appartiene ad un esercizio valido"
END
DATE F_DATAFCOMP
BEGIN
PROMPT 43 10 "Data di fine competenza "
WARNING "La data di fine competenza non puo' essere anteriore alla data di competenza"
END
BOOLEAN F_AUTOFCOMP
BEGIN
PROMPT 2 11 "Fine competenza coincidente con fine commessa di ogni riga"
MESSAGE FALSE ENABLE,F_DATAFCOMP
MESSAGE TRUE CLEAR,F_DATAFCOMP
END
STRING F_DESCR 50
BEGIN
PROMPT 2 12 "Descrizione "
END
STRINGA F_CODCAUS 3
BEGIN
PROMPT 2 13 "Causale "
USE LF_CAUSALI SELECT MOVIND!=''
INPUT CODCAUS F_CODCAUS
DISPLAY "Codice" CODCAUS
DISPLAY "Descrizione@50" DESCR
OUTPUT F_CODCAUS CODCAUS
OUTPUT F_DESCAUS DESCR
CHECKTYPE REQUIRED
FLAGS "U"
END
STRINGA F_DESCAUS 50 40
BEGIN
PROMPT 24 13 ""
USE LF_CAUSALI KEY 2 SELECT MOVIND!=''
INPUT DESCR F_DESCAUS
DISPLAY "Descrizione@50" DESCR
DISPLAY "Codice" CODCAUS
COPY OUTPUT F_CODCAUS
CHECKTYPE REQUIRED
END
STRING DLG_PROFILE 50
BEGIN
PROMPT 2 -2 "Profilo "
PSELECT
END
ENDPAGE
PAGE "Istruzioni " 0 2 0 0
TEXT -1
BEGIN
PROMPT 1 1 "@bIstruzioni"
END
TEXT -1
BEGIN
PROMPT 1 2 "_ Il file da importare DEVE essere in formato .csv. DEVE avere solo righe da importare (niente intestazioni o righe vuote!)"
END
TEXT -1
BEGIN
PROMPT 1 3 "_ Nel campo Cartella inserire il percorso completo della cartella che contiene il file da importare."
END
TEXT -1
BEGIN
PROMPT 1 4 "_ Nel campo File inserire il nome del file di tipo .csv da importare. Il nome NON deve contenere spazi."
END
TEXT -1
BEGIN
PROMPT 1 5 "_ Nel campo Separatore campi inserire il carattere di separazione tra i campi del file da importare (es. ';' o ',')."
END
TEXT -1
BEGIN
PROMPT 1 6 "_ Nel campo Separatore decimale inserire il carattere di separazione decimele degli importi (es. ',' o '.')."
END
TEXT -1
BEGIN
PROMPT 1 7 "_ I campi dei sepatratori dipendono dalle impostazioni del proprio computer. Si controllano aprendo il file di input con un editor di testo."
END
ENDPAGE
ENDMASK