Patch level :

Files correlati     :
Ricompilazione Demo : [ ]
Commento            :


git-svn-id: svn://10.65.10.50/branches/R_10_00@21755 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
cris 2011-03-09 08:43:33 +00:00
parent 3997f4fc08
commit caa1ffb980
7 changed files with 1099 additions and 186 deletions

View File

@ -4,16 +4,35 @@
#include <recarray.h>
#include <recset.h>
#include <reputils.h>
#include <textset.h>
#include <doc.h>
#include <rdoc.h>
#include "../mg/codcorr.h"
#include "../cg/cglib01.h"
#include "../ve/velib.h"
#include "ha2.h"
#include "ha2100a.h"
const char* const APPNAME = TR("Procedura Esselunga: generazione file Privat");
const char* const APPNAME = TR("Esselunga: generazione file Privat");
///////////////////////////////////////////////////////////
// TEsselunga_recordset: serve per potre scrivere il primo record che e' diverso dagli altri
///////////////////////////////////////////////////////////
class TEsselunga_recordset : public TAS400_recordset
{
protected:
//esportazione
void add_field(const char* name, const char* tipo, int pos, int len);
void insert_field(const char* name, const char* tipo, int pos, int len);
void add_eol_field();
//importazione
void add_trc_field(const char* tr, const char* name, const char* tipo, int pos, int len);
public:
TEsselunga_recordset(const int rec_length);
};
///////////////////////////////////////////////////////////
// TAutomask
@ -22,6 +41,7 @@ class THardy_esselunga_mask : public TAutomask
{
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
public:
THardy_esselunga_mask();
virtual ~THardy_esselunga_mask() {};
@ -60,18 +80,68 @@ bool THardy_esselunga_mask::on_field_event(TOperable_field& o, TField_event e, l
return true;
}
///////////////////////////////////////////////////////////
// TCodArtEsselunga_cache
///////////////////////////////////////////////////////////
class TCodArtEsselunga_cache : public TCache
{
protected:
virtual TObject* key2obj(const char* key);
public:
TCodArtEsselunga_cache() {}
};
TObject* TCodArtEsselunga_cache::key2obj(const char* key)
{
TToken_string code(key);
TString80 codart; code.get(0, codart);
TString16 codcf; code.get(1, codcf);
TISAM_recordset codcorr("USE CODCORR\nSELECT CODCF=#CODCF\nFROM CODART=#COD\nTO CODART=#COD");
codcorr.set_var("#COD", TVariant(codart));
codcorr.set_var("#CODCF", TVariant(codcf));
if (codcorr.items()>0)
{
codcorr.move_first();
return new TString80(codcorr.get(CODCORR_CODARTALT).as_string());
}
return NULL;
}
/////////////////////////////////////////////////////////////
// Recordset per file privat
/////////////////////////////////////////////////////////////
class TPrivat_recordset : public TAS400_recordset
{
public:
TPrivat_recordset();
};
TPrivat_recordset::TPrivat_recordset()
: TAS400_recordset("AS400(51)")
{
create_field("CDC", -1, 3, _intfld); // centro di costo
create_field("CODART", -1, 6, _longfld); // codice articolo
create_field("CODFORN", -1, 6, _longfld); // codice fornitore
create_field("TIPOBOLLA", -1, 1, _alfafld); // tipo bolla
create_field("NUMBOLLA", -1, 12, _alfafld); // numero bolla
create_field("DATABOLLA", -1, 8, _longfld); // data bolla
create_field("QTACONS", -1, 7, _realfld); // qta consegnata
create_field("QTARESA", -1, 7, _realfld); // qta resa
create_field("CODDIP", -1, 1, _alfafld); // codice dipendenza
}
///////////////////////////////////////
// TSkeleton_application
///////////////////////////////////////
class THardy_esselunga : public TSkeleton_application
{
protected:
void elabora(const TMask& mask);
long genera_recordset(const TMask& mask, TISAM_recordset& recset);
void elabora_documenti(const TMask& mask, TISAM_recordset& recset, TLog_report& log);
void elabora(const TMask& mask);
void check_date(const TDate& datafine, TDate& dataini);
bool check_cliente(const long codcf);
long check_cliente(const long codcf);
public:
virtual void main_loop();
@ -91,7 +161,7 @@ void THardy_esselunga::check_date(const TDate& datafine, TDate& dataini)
long THardy_esselunga::genera_recordset(const TMask& mask, TISAM_recordset& recset)
{
TString query;
query << "USE DOC ";
query << "USE DOC \n";
TString filt_expr;
// aggiungo alla query le condizioni sulle numerazioni selezionare da maschera
@ -100,21 +170,21 @@ long THardy_esselunga::genera_recordset(const TMask& mask, TISAM_recordset& recs
if (items > 0)
{
TString16 codnum;
filt_expr << " SELECT ";
filt_expr << " SELECT";
FOR_EACH_SHEET_ROW(sheet, r, row)
{
codnum = row->get(0);
if (codnum.not_empty())
{
filt_expr << "(CODNUM==\"";
filt_expr << codnum << "\") OR";
filt_expr << " (CODNUM=\"";
filt_expr << codnum << "\") ||";
}
}
filt_expr.rtrim(2);
query << filt_expr;
}
query << "\nFROM DATADOC=#DATAINI PROVV=D ANNO=#ANNO";
query << "\nTO DATADOC=#DATAFIN PROVV=D ANNO=#ANNO";
query << "\nFROM DATADOC=#DATAINI PROVV='D' ANNO=#ANNO";
query << "\nTO DATADOC=#DATAFIN PROVV='D' ANNO=#ANNO";
recset.set(query);
@ -133,164 +203,28 @@ long THardy_esselunga::genera_recordset(const TMask& mask, TISAM_recordset& recs
return recset.items();
}
/*
//metodo che riempie un array con tutti i contratti del cliente passatogli (in base alla tipologia di contratti da elaborare)
int THardy_esselunga::find_contratti_cliente(const long codcf, const TMask& mask, TArray& contratti_cliente)
{
contratti_cliente.destroy();
//deve cercare tutti i contratti del cliente e metterli nell'array
TString query;
query << "USE DOC KEY 4";
query << "\nSELECT ((TIPODOC=#A_TIPODOC)||(TIPODOC=#R_TIPODOC)||(TIPODOC=#P_TIPODOC))";
query << "\nFROM TIPOCF=C CODCF=#CODCF";
query << "\nTO TIPOCF=C CODCF=#CODCF";
TISAM_recordset recset(query);
//settaggio delle variabili
//il codice numerazione lo trova nella configurazione Hardy, e lo deve scegliere in base alla tipologia di contratti che sta esaminando!
TConfig config(CONFIG_DITTA, "ha");
const TString& tip_ant = config.get("CoAntTip");
const TString& tip_rifa = config.get("CoRifaTip");
const TString& tip_post = config.get("CoPostTip");
recset.set_var("#A_TIPODOC", tip_ant);
recset.set_var("#R_TIPODOC", tip_rifa);
recset.set_var("#P_TIPODOC", tip_post);
recset.set_var("#CODCF", codcf);
const long n_contratti = recset.items(); //questo serve solo al sagace programmatore
//aggiunge i contratti all'array: solo quelli in auge nel periodo di calcolo selezionato sulla maschera!
for (bool ok = recset.move_first(); ok; ok = recset.move_next())
{
//contratti anticipo 'A': datainizio esiste sempre, datafine non esiste (va ad esaurimento)
//contratti posticipo 'P': datainizio esiste sempre, datafine può non esistere
//contratti rifatturazione 'R': come contratti anticipo
//controlla validità del contratto con le date scelte per l'elaborazione dei documenti
const TDate data_ini_contratto = recset.get(DOC_DATACOMP).as_date();
TDate data_ini_elab = mask.get_date(F_DADATA);
const TDate data_fine_elab = mask.get_date(F_ADATA);
if (!data_ini_elab.ok())
check_date(data_fine_elab, data_ini_elab);
//quindi la datainizio vale per tutti allo stesso modo (è obbligatoria nei contratti)
//se l'elaborazione finisce prima che cominci il contratto -> il contratto non serve a nulla
if (data_ini_contratto > data_fine_elab)
continue;
//la data fine vale invece solo per i contratti 'P' e potrebbe non esserci (contratti senza scadenza)
TDate data_fine_contratto;
//se la data fine contratto non è valida (ma è presente!) non dobbiamo fare nulla, perchè il contratto non va elaborato
data_fine_contratto = recset.get(DOC_DATAFCOMP).as_date();
if (data_fine_contratto.ok())
{
if (data_fine_contratto < data_ini_elab)
continue;
}
//ci tocca istanziarci un contratto_premi
TContratto_premi* curr_contratto = new TContratto_premi(recset.cursor()->curr());
//azzeratore del campo con il totale reso per elaborazione, nel caso di contratti Anticipo/Rifatturazione, riga spese
const char tipo_contr = curr_contratto->tipo_contratto();
if (tipo_contr == 'A' || tipo_contr == 'R')
{
FOR_EACH_PHYSICAL_RDOC(*curr_contratto, r, rdoc)
{
if (rdoc->get(RDOC_TIPORIGA) == HARDY_TIPORIGA_SOMMA)
{
rdoc->zero(RCA_2_RESO_CORRENTE);
break;
}
}
}
contratti_cliente.add(curr_contratto);
}
return contratti_cliente.items();
}
bool THardy_esselunga::aggiorna_contratti(const TRiga_documento& rdoc, TContratto_premi& contratto)
{
bool elaborato = false;
const char tipo_contratto = contratto.tipo_contratto();
//parametri della riga fattura
TString80 rdoc_codart = rdoc.get(RDOC_CODART);
rdoc_codart.trim();
const real rdoc_qta = rdoc.get_real(RDOC_QTA);
const TString4 rdoc_umqta = rdoc.get(RDOC_UMQTA);
FOR_EACH_PHYSICAL_RDOC(contratto, rm, rigamerce)
{
const TString& rigamerce_codart = rigamerce->get(RDOC_CODART);
//se trova il codart in una delle righe di contratto...
if (rdoc_codart == rigamerce_codart)
{
const real rigamerce_premio = rigamerce->get_real(RC_1_PREMIO);
//se il premio non è nullo procede all'aggiornamento del restituito (solo contratti A/R e righe spese) e del bonus (tutti i contratti e righe merce)
if (rigamerce_premio != ZERO)
{
//normalizzazione della qta
const TString& umqta_tot = rigamerce->get(RDOC_UMQTA); //prende la UM dal contratto che farà da riferimento!
TArticolo articolo(rdoc_codart);
const real normalized_rdoc_qta = articolo.convert_to_um(rdoc_qta, umqta_tot, rdoc_umqta, true);
//aggiornamento delle righe di tipo spesa (verigh02) per aggiornare le somme restituite nel caso di contratti di anticipo/rifatturazione
if (tipo_contratto == 'A' || tipo_contratto == 'R')
{
FOR_EACH_PHYSICAL_RDOC(contratto, ra, rigacontratto)
{
//cerca una riga anticipo da evadere sul contratto per aggiornare la somma restituita sull'anticipo
if (rigacontratto->is_spese())
{
//si informa su quale fosse la somma anticipata
const real somma_anticipata = rigacontratto->get_real(RCA_2_ANTICIPATO);
//aggiorna la somma restituita dovuta al contratto (parte da zero per ogni elaborazione di NAC)
real somma_restituita = rigacontratto->get_real(RCA_2_RESO_CORRENTE);
//controlla che il contratto non sia per caso già stato pareggiato! quindi il reso deve essere < dell'anticipato per procedere
//la somma restituita deve essere incrementata per la qta di merce (caffè) che c'è sulla riga della fattura in esame...
//..moltiplicata per il premio che c'è nella riga di tipo merce del contratto in esame
somma_restituita += normalized_rdoc_qta * rigamerce_premio;
rigacontratto->put(RCA_2_RESO_CORRENTE, somma_restituita);
elaborato = true;
break;
}
} //FOR_EACH_PHYSICAL.. fine casino sulla riga di tipo spese
} //if(tipo_contratto == "A"...
//questo va bene invece per ogni riga merce (verigh01), sia per contratti di tipo A/R che di tipo P
if (rigamerce->is_merce())
{
real somma_bonus = rigamerce->get_real(RC_1_BONUS);
somma_bonus += normalized_rdoc_qta * rigamerce_premio;
rigamerce->put(RC_1_BONUS, somma_bonus);
rigamerce->add(RDOC_QTA, normalized_rdoc_qta); //riscrive sul campo di appoggio del contratto
elaborato = true;
}
} //if(rigamerce_premio != ZERO...
} //if(rdoc_codart...
} //FOR_EACH_PHYSICAL..
return elaborato;
}
*/
void THardy_esselunga::elabora_documenti(const TMask& mask, TISAM_recordset& recset, TLog_report& log)
void THardy_esselunga::elabora(const TMask& mask)
{
TLog_report log;
// lettura dei dati fissi da configurazione
TConfig config(CONFIG_DITTA, "ha");
const TString16 piva_esselunga = config.get("Esselunga_PIvaEsselunga");
const TString16 piva_hardy = config.get("Esselunga_PIvaHardy");
const TString16 cod_hardy = config.get("Esselunga_CodHardy");
const TString16 tipo_emissione = config.get("Esselunga_TipoEmissione");
const TString4 dipendenza = mask.get(F_DIPENDENZA);
TFilename file_privat = config.get("Esselunga_Path");
if (dipendenza[0] == 'D')
file_privat.add("CDMI");
else
file_privat.add("CDFI");
TISAM_recordset recset("");
const long items = genera_recordset(mask, recset);
if (items == 0)
log.log(1, "Non esistono documenti che soddisfano i parametri selezionati.");
// lettura dei documenti da recordset
TProgind pi(recset.items(), TR("Elaborazione documenti in corso..."), true, true);
TPrivat_recordset privat;
for (bool ok = recset.move_first(); ok; ok = recset.move_next())
{
if (!pi.addstatus(1))
@ -298,13 +232,26 @@ void THardy_esselunga::elabora_documenti(const TMask& mask, TISAM_recordset& rec
const long codcf = recset.get(DOC_CODCF).as_int();
// verificare se il cliente appartiene alla dipendenza selezionata e se ha tutti i parametri per poter essere inviato
if (check_cliente(codcf))
const long codcf_esselunga = check_cliente(codcf, dipendenza);
if ( codcf_esselunga > 0)
{
TDocumento* doc = new TDocumento(recset.cursor()->curr());
// passo tutte le righe del documento all'AS400recordset
FOR_EACH_PHYSICAL_RDOC(*doc, r, rigadoc)
{
TString80 codart_esselunga = ""; // decodifica tramite cache()
privat.new_rec("");
privat.set("CDC", TVariant(codcf_esselunga));
/*
privat.set("CODART",
privat.set("CODFORN",
privat.set("TIPOBOLLA",
privat.set("NUMBOLLA",
privat.set("DATABOLLA",
privat.set("QTACONS",
privat.set("QTARESA",
*/
privat.set("CODDIP", TVariant(dipendenza));
} //FOR_EACH...
delete doc;
} // if check_cliente...
@ -316,27 +263,14 @@ void THardy_esselunga::elabora_documenti(const TMask& mask, TISAM_recordset& rec
if (definitivo)
{
}
log.print_or_preview();
}
bool THardy_esselunga::check_cliente(const long codcf)
long THardy_esselunga::check_cliente(const long codcf)
{
return true;
}
void THardy_esselunga::elabora(const TMask& mask)
{
TLog_report log(APPNAME);
log.kill_duplicates();
log.log(0, "");
TISAM_recordset recset("");
const long items = genera_recordset(mask, recset);
if (items == 0)
log.log(1, "Non esistono documenti che soddisfano i parametri selezionati.");
elabora_documenti(mask, recset, log);
log.print_or_preview();
}
void THardy_esselunga::main_loop()
{
THardy_esselunga_mask mask;

View File

@ -21,7 +21,7 @@ END
ENDPAGE
PAGE "Procedura Esselunga Privat" -1 -1 78 18
PAGE "Esselunga: generazione file Privat" -1 -1 78 18
GROUPBOX DLG_NULL 78 3
BEGIN

View File

@ -6,6 +6,9 @@ int main(int argc, char** argv)
const int n = argc > 1 ? argv[1][1]-'0' : 0;
switch (n)
{
case 3:
hacnv400(argc, argv); //Conversione movimenti di magazzino HARDY
break;
case 2:
hacnv300(argc, argv); //Conversione scadenze HARDY
break;

View File

@ -1,3 +1,4 @@
int hacnv100(int argc, char* argv[]);
int hacnv200(int argc, char* argv[]);
int hacnv300(int argc, char* argv[]);
int hacnv300(int argc, char* argv[]);
int hacnv400(int argc, char* argv[]);

880
ha/hacnv400.cpp Executable file
View File

@ -0,0 +1,880 @@
#include "halib.h"
#include "hacnvlib.h"
#include "hacnv400a.h"
#include <applicat.h>
#include <automask.h>
#include <defmask.h>
#include <execp.h>
#include <progind.h>
#include <reprint.h>
#include <reputils.h>
#include <tabutil.h>
#include <utility.h>
const char* const APPNAME = TR("Conversione movimenti di magazzino");
///////////////////////////////////////////////////////////
// Movimenti
///////////////////////////////////////////////////////////
class THardy_movmag : public THardy_transfer
{
int _anno; // parametri per la query
TDate _dadata, _adata; // parametri per la query
TConfig* _conf; // ini in compilazione
long _kmovcont; // movimento contabile in esame
TArray* _righeiva; // array dele righe iva hardy
TArray* _righecont; // array delle righe contabili hardy
TAssoc_array* _ivaind; // array dei codici iva con % di indetraibilità
TAssoc_array* _ivaoma; // array dei codici iva per gli omaggi
protected:
bool scrivi_righe();
bool scrivi_righecont();
bool test_movcont();
bool conto_is_costoricavo(const int gr);
bool test_moviva();
void conto2campo(const TString& hd_tipoc, const TString& hd_key, TString4& tipoc, int& gr, int& co, long& so);
void rec2ini(const TRectype& rec);
void recset2rec(const TODBC_recordset& recset, TRectype& rec, const TString_array& lista_campi);
real get_imponibile(const TRectype& rec);
public:
virtual bool trasferisci();
THardy_movmag(const int anno, const TDate dadata, const TDate adata);
};
// carica il record campo con il record hardy in base alla configurazione
void THardy_movmag::recset2rec(const TODBC_recordset& recset, TRectype& rec, const TString_array& lista_campi)
{
TString campo_dest, campo_orig, valore, str;
FOR_EACH_ARRAY_ROW(lista_campi,i,row)
{
row->get(0, campo_dest);
row->get(1, campo_orig);
if (campo_orig.full())
{
if (campo_orig[0] == '_')
{
if (campo_orig.starts_with("_SCONTO")) // è uno sconto (ca..o!)
{
valore.cut(0);
real sconto;
TString8 field;
for (int i = 1; i < 6; i++)
{
field.format("Sconto%1d",i);
sconto = get_real(field);
sconto.round(2);
if (sconto != ZERO)
{
valore << sconto.string();
valore << "+";
}
}
if (valore.len()>0)
valore = valore.left(valore.len()-1);
} else
if (campo_orig.starts_with("_REAL")) // è un real
{
const TString80 campo = campo_orig.after(',');
real r = recset.get(campo).as_real();
valore = r.string();
} else
if (campo_orig.starts_with("_ROUND")) // arrotondo a due decimali
{
const TString80 campo = campo_orig.after(',');
real contenuto = recset.get(campo).as_real();
contenuto.round(2);
valore = contenuto.string();
} else
if (campo_orig.starts_with("_FISSO")) // valore fisso indicato in configurazione
{
valore = campo_orig.after(',');
valore.trim();
} else
if (campo_orig.starts_with("_STREXPR")) // formato _STREXPR, espressione
{
TExpression expr(campo_orig.after(','), _strexpr);
for (int v = 0; v < expr.numvar(); v++)
{
const char* varname = expr.varname(v);
expr.setvar(v, recset.get(varname).as_string());
}
valore = expr.as_string();
valore.trim();
} else
if (campo_orig.starts_with("_TAB")) // formato _TAB,<tabella da leggere>,<valore CODTAB>, <campo da leggere>
{
TToken_string elabora(campo_orig, ',');
const TString4 tab = elabora.get(1); // tabella da leggere
const TString16 codtab = recset.get(elabora.get()).as_string();
const TString16 campotab = elabora.get();
valore = cache().get(tab, codtab, campotab);
} else
if (campo_orig.starts_with("_TRADUCI"))
{
const TString80 campo = campo_orig.after(',');
const TString80 contenuto = recset.get(campo).as_string();
TConfig& ini = config();
valore = ini.get(contenuto,campo);
}
else
valore.cut(0);
}
else
valore = recset.get(campo_orig).as_string();
rec.put(campo_dest, valore);
}
}
}
// calcola conto campo a partire da conto hardy
void THardy_movmag::conto2campo(const TString& hd_tipoc, const TString& hd_key, TString4& tipoc, int& gr, int& co, long& so)
{
TConfig& ini = config();
char tipocc = hd_tipoc[0];
switch (tipocc)
{
case 'S':
{
tipoc = " ";
hd_key2conto(hd_key, gr, co, so);
}
break;
case 'C':
{
tipoc = "C";
so = hd_key2cli(hd_key);
TToken_string key(tipoc);
key.add(so);
const TRectype rec_cf = cache().get(LF_CLIFO, key);
gr = rec_cf.get_int(CLI_GRUPPO);
co = rec_cf.get_int(CLI_CONTO);
if (gr == 0)
{
gr = ini.get_int("CLI_GRUPPO", "Parametri");
co = ini.get_int("CLI_CONTO", "Parametri");
}
}
break;
case 'F':
{
tipoc = "F";
so = hd_key2forn(hd_key);
TToken_string key(tipoc);
key.add(so);
const TRectype rec_cf = cache().get(LF_CLIFO, key);
gr = rec_cf.get_int(CLI_GRUPPO);
co = rec_cf.get_int(CLI_CONTO);
if (gr == 0)
{
gr = ini.get_int("FOR_GRUPPO", "Parametri");
co = ini.get_int("FOR_CONTO", "Parametri");
}
}
break;
default:
break;
}
}
// verifica in configurazione se il conto è costo o ricavo
bool THardy_movmag::conto_is_costoricavo(const int gr)
{
TConfig& ini = config();
const int costi = ini.get_int("COSTI_GRUPPO", "Parametri");
const int ricavi = ini.get_int("RICAVI_GRUPPO", "Parametri");
return ((gr == costi) || (gr == ricavi));
}
// verifica se il movimento è iva e nel caso riempie array delle righe iva
bool THardy_movmag::test_moviva()
{
// verifico se è un movimento iva: esiste un record in MovIvaT
TString query;
query << query_header();
query << "SELECT * "
"FROM dbo.MovIvaT "
"WHERE KMovconT=";
query << _kmovcont;
TODBC_recordset recset(query);
real totdoc = ZERO;
long kregivat = -1;
if (recset.items() > 0)
{
bool ok=recset.move_first();
if (ok)
{
kregivat = recset.get("KRegivaT").as_int();
// aggiorna_testata movimento già scritta su ini con i nuovi dati di testata
const TString& key = recset.get("IdConto").as_string();
TString4 hdtipoc = recset.get("IdContoTp").as_string();
TString4 tipoc = " ";
int gr, co;
long so;
gr = 0;
co = 0;
so = 0;
conto2campo(hdtipoc, key, tipoc, gr, co, so);
_conf->set(MOV_TIPO, tipoc);
_conf->set(MOV_CODCF, so);
totdoc = recset.get("TotDocumento").as_real();
if (totdoc == ZERO)
_conf->set("SOLAIVA", "X");
_conf->set(MOV_TOTDOC, totdoc.string(0,2));
}
}
// leggo le righe iva e costrisco array corrispondente
TString_array lista_campi_righeiva;
TConfig& ini = config();
ini.list_variables(lista_campi_righeiva, true, "RMOVIVA", true);
TString query_righe;
query_righe << query_header();
query_righe << "SELECT * "
"FROM dbo.MovIva "
"WHERE KRegivaT=";
query_righe << kregivat;
TODBC_recordset recset_righe(query_righe);
_righeiva->destroy();
TLocalisamfile rmoviva(LF_RMOVIVA);
TRectype& rec_rmoviva = rmoviva.curr();
real totdoc_calc = ZERO;
for (bool ok=recset_righe.move_first();ok;ok=recset_righe.move_next())
{
recset2rec(recset_righe, rec_rmoviva, lista_campi_righeiva);
const TString& key = recset_righe.get("IdConto").as_string();
TString4 hdtipoc = recset_righe.get("IdContoTp").as_string();
TString4 tipoc;
tipoc = " ";
int gr, co;
long so;
gr = 0;
co = 0;
so = 0;
conto2campo(hdtipoc, key, tipoc, gr, co, so);
rec_rmoviva.put(RMI_TIPOC, tipoc);
rec_rmoviva.put(RMI_GRUPPO, gr);
rec_rmoviva.put(RMI_CONTO, co);
rec_rmoviva.put(RMI_SOTTOCONTO, so);
const TString& codiva = rec_rmoviva.get(RMI_CODIVA);
const TString* codind = (TString*)_ivaind->objptr(codiva);
if (codind != NULL)
rec_rmoviva.put(RMI_TIPODET, *codind);
_righeiva->add(new TRectype(rec_rmoviva));
if (!_ivaoma->is_key(codiva))
totdoc_calc+=recset_righe.get("Imponibile").as_real();
totdoc_calc+=recset_righe.get("Imposta").as_real();
}
if (totdoc == ZERO && totdoc_calc != ZERO)
{
_conf->set("SOLAIVA", " ");
_conf->set(MOV_TOTDOC, totdoc_calc.string(0,2));
}
return (kregivat > 0);
}
// riempie array delle righe contabili
bool THardy_movmag::test_movcont()
{
TString_array lista_campi_righe;
TConfig& ini = config();
ini.list_variables(lista_campi_righe, true, "RMOV", true);
TString query_righe;
query_righe << query_header();
query_righe << "SELECT * "
"FROM dbo.MovContabili "
"WHERE KMovconT=";
query_righe << _kmovcont;
TODBC_recordset recset_righe(query_righe);
_righecont->destroy();
TLocalisamfile rmov(LF_RMOV);
TRectype& rec_rmov = rmov.curr();
for (bool ok=recset_righe.move_first();ok;ok=recset_righe.move_next())
{
recset2rec(recset_righe, rec_rmov, lista_campi_righe);
const TString& key = recset_righe.get("IdConto").as_string();
TString4 hdtipoc = recset_righe.get("IdContoTp").as_string();
TString4 tipoc;
tipoc = " ";
int gr, co;
long so;
gr = 0;
co = 0;
so = 0;
conto2campo(hdtipoc, key, tipoc, gr, co, so);
TString4 sezione = "D";
real imp_dare = recset_righe.get("Dare").as_real();
real imp_avere = recset_righe.get("Avere").as_real();
if (imp_dare.is_zero())
sezione = "A";
rec_rmov.put(RMV_SEZIONE, sezione);
rec_rmov.put(RMV_IMPORTO, (imp_avere.is_zero() ? imp_dare : imp_avere));
rec_rmov.put(RMV_TIPOC, tipoc);
rec_rmov.put(RMV_GRUPPO, gr);
rec_rmov.put(RMV_CONTO, co);
rec_rmov.put(RMV_SOTTOCONTO, so);
_righecont->add(new TRectype(rec_rmov));
}
return true;
}
// scrive il record passato sull'ini corrente
void THardy_movmag::rec2ini(const TRectype& rec)
{
for (int i=0; i<rec.items(); i++)
{
const char* fieldname = rec.fieldname(i);
const TString& value = rec.get(fieldname);
if (!value.empty())
_conf->set(fieldname, value);
}
}
// scrive su ini le righe contabili
bool THardy_movmag::scrivi_righecont()
{
TString paragraph;
int nrigac = 1;
for (int i=0;i<_righecont->items();i++)
{
TRectype& rec_rmov = *(TRectype*)_righecont->objptr(i);
paragraph.format("%d,%d",LF_RMOV, nrigac++);
_conf->set_paragraph(paragraph); // riga contabile
rec2ini(rec_rmov);
}
return true;
}
// calcola imponibile della riga iva passata:
// 1. se è una riga con iva indetraibile verifico il conto 4 sulla causale
// se il conto c'è, l'imponibile è imponibile della riga
// se il conto non c'è calcolo iva indetraibile utilizzando la % e la sommo all'imponibile
// 2. se è una riga con iva normale, l'imponibile è imponibliie della riga
real THardy_movmag::get_imponibile(const TRectype& rec)
{
real imponibile = rec.get_real(RMI_IMPONIBILE);
const char* codiva = rec.get(RMI_CODIVA);
if (_ivaind->is_key(codiva))
{
TString16 causale = get_str("IdCausale");
causale << "|4";
const TString& gruppo = cache().get(LF_RCAUSALI, causale, RCA_GRUPPO);
if (gruppo.blank())
{
real imposta = rec.get_real(RMI_IMPOSTA);
TString& codind = (TString&)_ivaind->find(codiva);
real perc(cache().get("%DET", codind, "R0"));
imposta = (imposta*perc)/CENTO + 0,01;
imposta.round(2);
imponibile+=imposta;
}
}
return imponibile;
}
// gestisce tutto il procedimento di scrittura su ini delle righe iva e contabili
bool THardy_movmag::scrivi_righe()
{
const int ndec = TCurrency::get_firm_dec(false);
TString paragraph;
int nrigai = 1; // contatore righe iva
TConfig& ini = config();
TString8 iva_esente = ini.get("IVA_ESENTE", "Parametri");
TToken_string sconto_omaggi = ini.get("CONTO_OMAGGI", "Parametri");
TToken_string conti_mov = ini.get("CONTI_MOV", "Parametri");
const int gruppo_omaggi = sconto_omaggi.get_int(0);
const int conto_omaggi = sconto_omaggi.get_int(1);
const long sottoconto_omaggi = sconto_omaggi.get_long(2);
real saldo;
// la sezione della riga 1 mi serve per verificare il segno e la sezione delle righe contabili
TString16 causale = get_str("IdCausale");
causale << "|1";
const char sez_cau = (cache().get(LF_RCAUSALI, causale, RCA_SEZIONE)[0] == 'D' ? 'A' : 'D');
bool has_iva_omaggio = false;
// se è un movimento iva metto in atto il meccanismo di ricerca per assegnare le aliquote ai conti
if (_righeiva->items() > 0)
{
for (int i = 0; !has_iva_omaggio && i<_righeiva->items(); i++)
has_iva_omaggio = _ivaoma->is_key(((TRectype*)_righeiva->objptr(i))->get(RMI_CODIVA));
// primo passo: scartare le righe contabili con gruppi non presenti nella lista GRUPPI_MOV
for (int i=_righecont->items() - 1;i>=0;i--)
{
TRectype& rec_rmov = *(TRectype*)_righecont->objptr(i);
const int gruppo = rec_rmov.get_int(RMV_GRUPPO);
const int conto = rec_rmov.get_int(RMV_CONTO);
const long sottoconto = rec_rmov.get_long(RMV_SOTTOCONTO);
TToken_string key;
key.add(gruppo);
key.add(conto);
const int tipoconto = atoi(cache().get(LF_PCON, key, PCN_INDBIL));
const bool riga_omaggio = (gruppo == gruppo_omaggi) && (conto == conto_omaggi) && (sottoconto == sottoconto_omaggi);
const TString & descr = rec_rmov.get(RMV_DESCR);
// se la descrizione comincia con queste stringhe, significa che è un pagamento immediato
// e va passata la riga contabile cosi come è
if (descr.starts_with("S.DO DOC.") || descr.starts_with("ABB. DOC.") || descr.starts_with("ACC. DOC."))
rec_rmov.put(RMV_ROWTYPE, "C");
else
if (riga_omaggio)
{
if (!has_iva_omaggio)
{
paragraph.format("%d,%d",LF_RMOVIVA, nrigai++);
_conf->set_paragraph(paragraph); // riga iva
rec2ini(*(TRectype*)_righeiva->objptr(0));
// sostituisco codice iva e importo (-) e gruppo conto sottoconto
const char sezione = rec_rmov.get_char(RMV_SEZIONE);
real importo = rec_rmov.get_real(RMV_IMPORTO);
if (sezione != sez_cau)
importo = -importo;
saldo += importo;
_conf->set(RMI_CODIVA, iva_esente); // codice iva esente per quadrare il movimento
_conf->set(RMI_TIPODET, "");
_conf->set(RMI_IMPONIBILE, importo.string(0,2)); // imponibile negativo
_conf->set(RMI_IMPOSTA, ""); // imposta zero
_conf->set(RMI_TIPOC, "");
_conf->set(RMI_GRUPPO, sconto_omaggi.get(0));
_conf->set(RMI_CONTO, sconto_omaggi.get(1));
_conf->set(RMI_SOTTOCONTO, sconto_omaggi.get(2));
}
_righecont->destroy(i);
}
else
{
bool found = (tipoconto == 3) || (tipoconto == 4);
if (!found)
{
TToken_string cod("", ',');
cod.add(gruppo);
cod.add(conto);
cod.add(sottoconto);
// Provo il sottoconto ma se non riesco provo con conto e poi anche gruppo (formato -> 3,1,2 o 3,1,0 o 3,0,0)
for (int c = 2; !found && c >= 0; c--)
{
found = conti_mov.get_pos(cod) >= 0;
cod.add(0, c);
}
if (!found)
_righecont->destroy(i);
}
if (found)
{
const char sezione = rec_rmov.get_char(RMV_SEZIONE);
if (sezione != sez_cau)
{
real importo = rec_rmov.get_real(RMV_IMPORTO);
importo = -importo;
rec_rmov.put(RMV_SEZIONE, sez_cau);
rec_rmov.put(RMV_IMPORTO, importo);
}
}
}
}
_righecont->pack();
const bool singola_rigacont = (_righecont->items()==1);
// secondo passo: per ogni riga iva cerco importo uguale in righe contabili,
// se lo trovo assegno quel codice iva al conto contabile trovato e cancello la riga iva e la riga contabile
for (int i=0;i<_righeiva->items();i++)
{
TRectype& rec_rmoviva = *(TRectype*)_righeiva->objptr(i);
const char* codiva = rec_rmoviva.get(RMI_CODIVA);
const bool riga_omaggio = _ivaoma->is_key(codiva);
// se le righe contabili sono 1, su tutte le righe iva metto quel conto, da brava massaia ...
if ((!riga_omaggio) && _righecont->items()==1)
{
TRectype& rec_rmov = *(TRectype*)_righecont->objptr(0);
rec_rmoviva.put(RMI_TIPOC, rec_rmov.get(RMV_TIPOC));
rec_rmoviva.put(RMI_GRUPPO, rec_rmov.get(RMV_GRUPPO));
rec_rmoviva.put(RMI_CONTO, rec_rmov.get(RMV_CONTO));
rec_rmoviva.put(RMI_SOTTOCONTO, rec_rmov.get(RMV_SOTTOCONTO));
paragraph.format("%d,%d",LF_RMOVIVA, nrigai++);
_conf->set_paragraph(paragraph); // riga iva
rec2ini(rec_rmoviva);
rec_rmoviva.zero();
}
else
{
TCodiceIVA c(codiva);
real imponibile = get_imponibile(rec_rmoviva);
for (int j=0;j<_righecont->items();j++)
{
TRectype& rec_rmov = *(TRectype*)_righecont->objptr(j);
const bool riga_cont = (rec_rmov.get(RMV_ROWTYPE) == "C");
real importo = rec_rmov.get_real(RMV_IMPORTO);
if ((!riga_omaggio) && (!riga_cont) && (importo <= imponibile))
{
const real impon = rec_rmoviva.get_real(RMI_IMPONIBILE);
const real iva = rec_rmoviva.get_real(RMI_IMPOSTA);
c.imposta(importo);
rec_rmoviva.put(RMI_TIPOC, rec_rmov.get(RMV_TIPOC));
rec_rmoviva.put(RMI_GRUPPO, rec_rmov.get(RMV_GRUPPO));
rec_rmoviva.put(RMI_CONTO, rec_rmov.get(RMV_CONTO));
rec_rmoviva.put(RMI_SOTTOCONTO, rec_rmov.get(RMV_SOTTOCONTO));
real wimp = impon ;
if (importo < imponibile)
{
wimp *= importo / imponibile;
wimp.round(2);
}
const real wiva = c.imposta(wimp);
if (importo < imponibile)
{
rec_rmoviva.put(RMI_IMPONIBILE, wimp);
rec_rmoviva.put(RMI_IMPOSTA, wiva);
}
paragraph.format("%d,%d",LF_RMOVIVA, nrigai++);
_conf->set_paragraph(paragraph); // riga iva
rec2ini(rec_rmoviva);
_righecont->destroy(j, true);
j = _righecont->items();
if (importo == imponibile)
rec_rmoviva.zero();
else
{
rec_rmoviva.put(RMI_IMPONIBILE, impon - wimp);
rec_rmoviva.put(RMI_IMPOSTA, iva - wiva);
}
}
}
}
}
_righecont->pack();
// terzo passo: per ogni riga iva rimasta distribuisco importo su tutti i conti rimasti in righe cont.
for (int i=0;i<_righeiva->items();i++)
{
TRectype& rec_rmoviva = *(TRectype*)_righeiva->objptr(i);
if (!rec_rmoviva.empty())
{
const TString& codiva = rec_rmoviva.get(RMI_CODIVA);
const bool riga_omaggio = _ivaoma->is_key(codiva);
real imponibile = rec_rmoviva.get_real(RMI_IMPONIBILE);
real imposta = rec_rmoviva.get_real(RMI_IMPOSTA);
TGeneric_distrib dimponibile(imponibile, ndec);
TGeneric_distrib dimposta(imposta, ndec);
for (int j=0;j<_righecont->items();j++)
{
TRectype& rec_rmov = *(TRectype*)_righecont->objptr(j);
const bool riga_cont = (rec_rmov.get(RMV_ROWTYPE) == "C");
if (!riga_cont)
{
real importo = rec_rmov.get_real(RMV_IMPORTO);
dimponibile.add(importo);
dimposta.add(importo);
}
}
for (int j=0;j<_righecont->items();j++)
{
TRectype& rec_rmov = *(TRectype*)_righecont->objptr(j);
const bool riga_cont = (rec_rmov.get(RMV_ROWTYPE) == "C");
if (!riga_cont)
{
real importo = dimponibile.get();
real imposta = dimposta.get();
rec_rmoviva.put(RMI_TIPOC, rec_rmov.get(RMV_TIPOC));
rec_rmoviva.put(RMI_GRUPPO, rec_rmov.get(RMV_GRUPPO));
rec_rmoviva.put(RMI_CONTO, rec_rmov.get(RMV_CONTO));
rec_rmoviva.put(RMI_SOTTOCONTO, rec_rmov.get(RMV_SOTTOCONTO));
rec_rmoviva.put(RMI_IMPONIBILE, importo);
rec_rmoviva.put(RMI_IMPOSTA, imposta);
paragraph.format("%d,%d",LF_RMOVIVA, nrigai++);
_conf->set_paragraph(paragraph); // riga iva
rec2ini(rec_rmoviva);
}
}
// se iva utilizzata per gli omaggi, devo fare un'altra riga iva identica ma con importo avere con iva esente e gr/co/so letto da configurazione CONTO_OMAGGI
if (riga_omaggio)
{
paragraph.format("%d,%d",LF_RMOVIVA, nrigai++);
_conf->set_paragraph(paragraph); // riga iva
rec2ini(rec_rmoviva);
// sostituisco codice iva e importo (-) e gruppo conto sottoconto
imponibile = -imponibile;
_conf->set(RMI_CODIVA, iva_esente); // codice iva esente per quadrare il movimento
_conf->set(RMI_TIPODET, "");
_conf->set(RMI_IMPONIBILE, imponibile.string(0,2)); // imponibile negativo
_conf->set(RMI_IMPOSTA, ""); // imposta zero
_conf->set(RMI_TIPOC, "");
_conf->set(RMI_GRUPPO, sconto_omaggi.get(0));
_conf->set(RMI_CONTO, sconto_omaggi.get(1));
_conf->set(RMI_SOTTOCONTO, sconto_omaggi.get(2));
}
}
}
for (int j=_righecont->items()-1;j>=0;j--)
{
TRectype& rec_rmov = *(TRectype*)_righecont->objptr(j);
const bool riga_cont = (rec_rmov.get(RMV_ROWTYPE) == "C");
if (riga_cont)
rec_rmov.zero(RMV_ROWTYPE);
else
_righecont->destroy(j, true);
}
if (saldo != ZERO)
{
TString paragraph;
paragraph.format("%d",LF_MOV);
real totdoc(_conf->get(MOV_TOTDOC, paragraph));
totdoc += saldo;
_conf->set(MOV_TOTDOC, totdoc.string(0,2), paragraph);
}
//_righecont->destroy();
}
// scrivo su ini le righe contabili rimaste (tutte se il mov non è iva)
scrivi_righecont();
return true;
}
// procedura principale di conversione
bool THardy_movmag::trasferisci()
{
TConfig& ini = config();
// creazione array delle aliquote iva con % indetraibilità e degli omaggi
// leggere la tabella hardy AliquoteIVA
_ivaind->destroy();
_ivaoma->destroy();
TString query_iva;
query_iva << query_header();
query_iva << "SELECT * "
"FROM dbo.AliquoteIVA ";
TODBC_recordset recset_iva(query_iva);
for (bool ok=recset_iva.move_first();ok;ok=recset_iva.move_next())
{
const char* codiva = recset_iva.get("IdIva").as_string();
real ind = recset_iva.get("Indetraibilita").as_real();
const int flomaggio = recset_iva.get("FlOmaggio").as_int();
if (ind != ZERO)
{
TString4 oggetto = ini.get(codiva, "Indetraibilita");
_ivaind->add(codiva, oggetto);
}
if (flomaggio > 0)
{
real* oggetto = new real();
_ivaoma->add(codiva, (TObject*)oggetto);
}
}
// query su testate movimenti
TString16 dastr, astr;
dastr.format("%4d-%2d-%2d", _dadata.year(), _dadata.month(), _dadata.day());
astr.format("%4d-%2d-%2d", _adata.year(), _adata.month(), _adata.day());
TString query =
"SELECT * "
"FROM dbo.MovContabiliT "
"WHERE Esercizio=";
query << _anno;
query << " AND DataMovimento>= '";
query << dastr;
query << "' AND DataMovimento<= '";
query << astr;
query << "' ORDER BY DataMovimento ";
TRecordset& recset = create_recordset(query);
TString_array lista_campi;
ini.list_variables(lista_campi, true, "MOV", true);
TFilename outdir;
outdir = ini.get("PATH", "Main");
TFilename listfiles = outdir; listfiles.add("ha*.ini");
TString_array transactions;
list_files(listfiles, transactions);
FOR_EACH_ARRAY_ROW(transactions, row, name)
remove(*name);
_conf = NULL;
long ntran = 1L;
TString paragraph;
THardy_iterator hi(this);
while (++hi)
{
_kmovcont = recset.get("KMovconT").as_int(); // numero movimento testata
if (_conf != NULL)
delete _conf;
_conf = NULL;
TFilename temp(outdir);
temp.add(format("ha%06ld", ntran++));
temp.ext("ini");
if (temp.exist())
temp.fremove();
_conf = new TConfig(temp);
_conf->set_paragraph("Transaction");
_conf->set("Action","INSERT");
_conf->set("Mode", "AUTO");
paragraph.format("%d",LF_MOV);
_conf->set_paragraph(paragraph); // testata movimento
aggiorna_ini(*_conf, lista_campi);
TString codcaus = _conf->get(MOV_CODCAUS);
if (cache().get(LF_CAUSALI, codcaus, CAU_MOVAP) == "C")
{
const TDate d(_conf->get(MOV_DATAREG));
const TDate datacomp(31, 12, d.year() - 1);
_conf->set(MOV_DATACOMP, datacomp.string());
}
// verifica se è un mov. iva e nel caso aggiorna testata e array righe iva
bool iva = test_moviva();
// legge righe contabili e aggiorna array righe cont.
test_movcont();
// scrive RMOV e /o RMOVIVA a partire da array righe letti da db hardy
bool ok = scrivi_righe();
if (!ok)
{
ntran--;
if (temp.exist())
temp.fremove();
TString msg;
msg << (iva ? TR("Il movimento iva "): TR("Il movimento contabile ")) << _kmovcont
<< TR(" ha generato un errore, non è stato convertito ");
log(msg, 2); // Non uso log_error per non dare messaggi fuorvianti
}
#ifdef DBG
else
{
TString msg;
msg << (iva ? TR("Movimento iva "): TR("Movimento contabile ")) << _kmovcont
<< TR(" generato nel file ") << temp;
log(msg);
}
#endif
}
if (_conf != NULL)
delete _conf;
show_log();
if (yesno_box(FR("Si desidera confermare l'importazione di %ld movimenti"), ntran-1))
{
TString app;
app << "cg2 -0 -i" << outdir << "/ha*.ini";
TExternal_app primanota(app);
primanota.run(true);
}
return true;
}
THardy_movmag::THardy_movmag(const int anno, const TDate dadata, const TDate adata) : _anno(anno), _dadata(dadata), _adata(adata)
{
_righeiva = new TArray;
_righecont = new TArray;
_ivaind = new TAssoc_array;
_ivaoma = new TAssoc_array;
}
///////////////////////////////////////////////////////////
// TConvMovMagHardy_mask
///////////////////////////////////////////////////////////
class TConvMovMagHardy_mask : public TAutomask
{
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
void serialize(bool bSave);
public:
void trasferisci();
TConvMovMagHardy_mask();
virtual ~TConvMovMagHardy_mask();
};
// Funzione di trasferimento dati da/verso file .ini con lo stesso nome della maschera
// Andrebbe messo in libreria
void TConvMovMagHardy_mask::serialize(bool bSave)
{
TFilename n = source_file(); n.ext("ini"); // Construisce il nome del .ini in base al .msk
TConfig cfg(n, "Main"); // Crea il file di configurazione
TString4 id;
for (int i = fields()-1; i >= 0; i--) // Scandisce tutti i campi della maschera ...
{
TMask_field& f = fld(i);
if (f.active() && f.is_loadable()) // ... selezionando solo quelli editabili
{
id.format("%d", f.dlg());
if (bSave) // A seconda del flag di scrittura ...
cfg.set(id, f.get()); // ... o scrive sul .ini
else
f.set(cfg.get(id)); // ... o legge dal .ini
}
}
}
void TConvMovMagHardy_mask::trasferisci()
{
TString query_header;
query_header << "ODBC(" << get(F_DSN) << ',' << get(F_USR) << ',' << get(F_PWD) << ")\n";
const int anno = get_int(F_ANNO);
const TDate dadata = get_date(F_DADATA);
const TDate adata = get_date(F_ADATA);
if (anno!=0)
{
THardy_log log;
THardy_movmag pc(anno, dadata, adata);
pc.init(TR("Movimenti contabili"), query_header, log);
pc.trasferisci();
}
}
bool TConvMovMagHardy_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
{
case DLG_OK:
if (e == fe_button)
serialize(true);
break;
default:
break;
}
return true;
}
TConvMovMagHardy_mask::TConvMovMagHardy_mask() : TAutomask("hacnv400a")
{
serialize(false);
}
TConvMovMagHardy_mask::~TConvMovMagHardy_mask()
{
}
///////////////////////////////////////////////////////////
// TConvMovMagHardy
///////////////////////////////////////////////////////////
class TConvMovMagHardy : public TSkeleton_application
{
protected:
virtual void main_loop();
};
void TConvMovMagHardy::main_loop()
{
TConvMovMagHardy_mask mask;
while (mask.run() == K_ENTER)
mask.trasferisci();
}
int hacnv400(int argc, char* argv[])
{
TConvMovMagHardy ih;
ih.run(argc, argv, APPNAME);
return 0;
}

15
ha/hacnv400a.h Executable file
View File

@ -0,0 +1,15 @@
#ifndef __HACNV200A_H
#define __HACNV200A_H
#define F_FIRM 101
#define F_RAGSOC 102
#define F_ANNO 111
#define F_DADATA 112
#define F_ADATA 113
#define F_DSN 201
#define F_USR 202
#define F_PWD 203
#endif

80
ha/hacnv400a.uml Executable file
View File

@ -0,0 +1,80 @@
#include "hacnv400a.h"
TOOLBAR "topbar" 0 0 0 2
#include <elabar.h>
ENDPAGE
PAGE "Conversione movimenti di magazzino" 0 2 0 0
GROUPBOX DLG_NULL 78 3
BEGIN
PROMPT 1 1 "@bDitta"
END
NUMBER F_FIRM 5
BEGIN
PROMPT 2 2 ""
USE LF_NDITTE
INPUT CODDITTA F_FIRM
OUTPUT F_RAGSOC RAGSOC
CHECKTYPE REQUIRED
FLAGS "DF"
END
STRING F_RAGSOC 60
BEGIN
PROMPT 17 2 ""
FLAGS "D"
END
GROUPBOX DLG_NULL 78 4
BEGIN
PROMPT 1 4 "@bSelezioni"
END
NUMBER F_ANNO 4
BEGIN
PROMPT 2 5 "Esercizio "
END
DATE F_DADATA
BEGIN
PROMPT 2 6 "Dal "
END
DATE F_ADATA
BEGIN
PROMPT 35 6 "Al "
END
ENDPAGE
PAGE "Configurazione" -1 -1 78 18
GROUPBOX DLG_NULL 78 5
BEGIN
PROMPT 1 1 "@bDatabase"
END
STRING F_DSN 30
BEGIN
PROMPT 2 2 "DSN "
CHECKTYPE REQUIRED
END
STRING F_USR 16
BEGIN
PROMPT 2 3 "User "
END
STRING F_PWD 16
BEGIN
PROMPT 2 4 "Password "
FLAGS "*"
END
ENDPAGE
ENDMASK