diff --git a/ha/ha2100.cpp b/ha/ha2100.cpp index 91d36c056..c652fd33d 100755 --- a/ha/ha2100.cpp +++ b/ha/ha2100.cpp @@ -4,16 +4,35 @@ #include #include #include +#include #include #include +#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; diff --git a/ha/ha2100a.uml b/ha/ha2100a.uml index 825aed417..e27a526f8 100755 --- a/ha/ha2100a.uml +++ b/ha/ha2100a.uml @@ -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 diff --git a/ha/hacnv.cpp b/ha/hacnv.cpp index 537b1e7a4..553294b1c 100755 --- a/ha/hacnv.cpp +++ b/ha/hacnv.cpp @@ -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; diff --git a/ha/hacnv.h b/ha/hacnv.h index ce9da7b82..e6347f254 100755 --- a/ha/hacnv.h +++ b/ha/hacnv.h @@ -1,3 +1,4 @@ int hacnv100(int argc, char* argv[]); int hacnv200(int argc, char* argv[]); -int hacnv300(int argc, char* argv[]); \ No newline at end of file +int hacnv300(int argc, char* argv[]); +int hacnv400(int argc, char* argv[]); \ No newline at end of file diff --git a/ha/hacnv400.cpp b/ha/hacnv400.cpp new file mode 100755 index 000000000..798e98040 --- /dev/null +++ b/ha/hacnv400.cpp @@ -0,0 +1,880 @@ +#include "halib.h" +#include "hacnvlib.h" +#include "hacnv400a.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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,,, + { + 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; iset(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; +} + diff --git a/ha/hacnv400a.h b/ha/hacnv400a.h new file mode 100755 index 000000000..041364a65 --- /dev/null +++ b/ha/hacnv400a.h @@ -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 diff --git a/ha/hacnv400a.uml b/ha/hacnv400a.uml new file mode 100755 index 000000000..60ba35350 --- /dev/null +++ b/ha/hacnv400a.uml @@ -0,0 +1,80 @@ +#include "hacnv400a.h" + +TOOLBAR "topbar" 0 0 0 2 + +#include + +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