From 17e79bc7c994d3fbdea4b21b53cf39c4f44ef54f Mon Sep 17 00:00:00 2001 From: alex Date: Tue, 11 Mar 2008 15:50:42 +0000 Subject: [PATCH] Patch level : 4.0 905 Files correlati : Ricompilazione Demo : [ ] Commento : Riportata la versione 3.2 patch 1092 git-svn-id: svn://10.65.10.50/trunk@16293 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- ef/df900000.frm | 7 - ef/riba.ini | 5 +- m770/777100.cpp | 322 ++++--- m770/777200.cpp | 4 +- mg/mg3600.cpp | 54 +- mg/mgmenu.men | 1 + mr/mr0100.cpp | 14 +- mr/mr2200.cpp | 61 +- mr/mr2201.cpp | 72 +- mr/mr2201.h | 17 +- or/or1.cpp | 4 +- or/or1.h | 1 + or/or1400.cpp | 545 ++++++++++++ or/or1400a.h | 53 ++ or/or1400a.uml | 514 ++++++++++++ or/ormenu.men | 3 +- ps/indice_programmi.txt | 5 +- ps/pf0001100.cpp | 4 +- ps/pf0001100.uml | 2 +- ps/pg0069.cpp | 2 +- ps/pg0069100.cpp | 2 +- ps/ps0920100.cpp | 79 +- ps/ps0920100a.uml | 4 +- ps/pt0002.cpp | 16 + ps/pt0002.h | 1 + ps/pt0002100.cpp | 483 +++++++++++ ps/pt0002100a.h | 7 + ps/pt0002100a.uml | 67 ++ ps/pt0002conf.ini | 6 + sv/sv1200.cpp | 84 +- sv/sv1200a.h | 1 + sv/sv1200a.uml | 9 +- tc/tc0300.cpp | 63 +- tc/tc0300a.uml | 83 +- tc/tc0700.cpp | 35 +- tc/tc0701.cpp | 166 ++-- tc/tc0701.h | 10 +- tc/tc9.cpp | 4 +- tc/tc9100.cpp | 1623 +----------------------------------- tc/tc9100a.h | 34 +- tc/tc9100a.ini | 423 ---------- tc/tc9100a.uml | 170 +--- tc/tc9100conf.ini | 5 +- tc/tc9200.cpp | 384 +-------- tc/tcconf.h | 17 +- tc/tctscau.uml | 17 +- tc/tctscdp.uml | 16 +- tc/tctsnaz.uml | 29 +- tc/tctsreg.uml | 56 +- tp/tp0100.cpp | 2 + tp/tp0100.h | 16 +- tp/tp0100a.h | 2 + tp/tp0100a.uml | 11 +- tp/tp0102.cpp | 70 +- xvaga/MD5Checksum.cpp | 536 ++++++++++++ xvaga/MD5Checksum.h | 342 ++++++++ xvaga/MD5ChecksumDefines.h | 119 +++ xvaga/email.cpp | 120 +++ xvaga/email.h | 40 + xvaga/msg.h | 69 ++ xvaga/smapi.cpp | 498 +++++++++++ xvaga/smapi.h | 52 ++ xvaga/xvaga.cpp | 11 +- xvaga/xvt.h | 3 + xvaga/xvtextra.cpp | 30 + xvaga/xvtmail.cpp | 32 +- 66 files changed, 4550 insertions(+), 2987 deletions(-) create mode 100755 or/or1400.cpp create mode 100755 or/or1400a.h create mode 100755 or/or1400a.uml create mode 100755 ps/pt0002.cpp create mode 100755 ps/pt0002.h create mode 100755 ps/pt0002100.cpp create mode 100755 ps/pt0002100a.h create mode 100755 ps/pt0002100a.uml create mode 100755 ps/pt0002conf.ini create mode 100755 xvaga/MD5Checksum.cpp create mode 100755 xvaga/MD5Checksum.h create mode 100755 xvaga/MD5ChecksumDefines.h create mode 100755 xvaga/email.cpp create mode 100755 xvaga/email.h create mode 100755 xvaga/msg.h create mode 100755 xvaga/smapi.cpp create mode 100755 xvaga/smapi.h diff --git a/ef/df900000.frm b/ef/df900000.frm index e4e15cd80..8ec8fa3fb 100755 --- a/ef/df900000.frm +++ b/ef/df900000.frm @@ -43,7 +43,6 @@ BEGIN KEY "denominazione banca presentazione" PROMPT 38 1 "Al/Alla @B" FIELD 202@->S0 -// MESSAGE _BANCAP END STRING 2 30 @@ -151,7 +150,6 @@ BEGIN KEY "codice fiscale" PROMPT 2 3 "P.I. " FIELD 20->PAIV -// FIELD 20->COFI END STRING 28 2 1 @@ -258,14 +256,12 @@ STRING 24 17 5 BEGIN KEY "dati fattura" PROMPT 92 1 "" -// MESSAGE _FATT,!DATIFATT END DATA 25 10 BEGIN KEY "data scadenza" PROMPT 112 1 "" -// FIELD 31->DATASCAD END STRING 34 20 @@ -333,7 +329,6 @@ SECTION RIGHE_EFFETTO 5 1 1 FILE 14 GROUP NPROGTR BEGIN PROMPT 124 1 "" FIELD 14->IMPORTOVAL - // PICTURE "###.###.###.###,@@#" GROUP 3 END @@ -341,7 +336,6 @@ SECTION RIGHE_EFFETTO 5 1 1 FILE 14 GROUP NPROGTR BEGIN PROMPT 124 1 "" FIELD 14->IMPORTO - // PICTURE "###.###.###.###" GROUP 4 FLAGS "D" END @@ -416,7 +410,6 @@ BEGIN KEY "test sulla valuta" PROMPT 34 3 "" FIELD CODVAL -// MESSAGE EMPTY ENABLE,4@|DISABLE,3@ GROUP 4 END diff --git a/ef/riba.ini b/ef/riba.ini index b1d53b35c..8821a1569 100755 --- a/ef/riba.ini +++ b/ef/riba.ini @@ -541,13 +541,14 @@ NAME(7)=ZERO FILLED TYPE(7)=NUMERO POSITION(7)=52 LENGTH(7)=15 +PICTURE(7)= @@@@@@@@@@@@@@@ +MESSAGE(7)=_IMPORTO,!TOT NAME(8)=IMPORTO TOTALE DEL FLUSSO TYPE(8)= NUMERO POSITION(8)=67 LENGTH(8)=15 -PICTURE(8)= @@@@@@@@@@@@@@@ -MESSAGE(8)=_IMPORTO,!TOT + NAME(9)=NUMERO RECORD TYPE(9)= NUMERO diff --git a/m770/777100.cpp b/m770/777100.cpp index bd0a7a392..be12b305e 100755 --- a/m770/777100.cpp +++ b/m770/777100.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include "base.h" @@ -23,8 +24,8 @@ static int anno_dic() { - static int anno = 0; - if (anno == 0) + static anno = 0; + if (anno <= 0) { TConfig ini(CONFIG_STUDIO); anno = ini.get_int("AnnoDic"); @@ -48,6 +49,7 @@ class TForm770 : public TForm int _index; TArray _records; TPointer_array _positions; + TAssoc_array _riep_ss; protected: bool compatible(const TRectype& r1, const TRectype& r2); @@ -68,6 +70,7 @@ protected: public: long trasfer(long codditta, TTrasferimento770& file, char tipo, int rpm); + TAssoc_array& riepilogo_ss() { return _riep_ss; } TForm770(const char* name); virtual ~TForm770(); @@ -162,11 +165,15 @@ public: void set(int pos, char val); void set(int pos, bool val); bool add(const char* code, const char* val); + bool add(const char* code, const real& val); const char* get(int pos, TString& str) const; int get_int(int pos) const; char get_char(int pos) const; + bool np_get(int pos, TString& key, TString& val) const; + bool np_get_real(int pos, TString& key, real& val) const; + const TRecord770& operator=(const TRecord770& rec) { _buffer = rec._buffer; return *this; } @@ -175,7 +182,7 @@ public: { _buffer[0] = tipo; tracciato().auto_fill(_buffer); } void azzera_campi_non_posizionali(); - bool ha_campi_non_posizionali() const { return strchr("EH", tipo_record()) != NULL; } + bool ha_campi_non_posizionali() const { return strchr("EHJ", tipo_record()) != NULL; } bool ha_campi_non_posizionali_compilati() const { return _buffer[90] > ' '; } @@ -205,6 +212,9 @@ class TTrasferimento770 : public TObject TString _ragsoc_dic; bool _save_headers; +protected: + void riepiloga_ss(const TRecord770& rec, TArray& riep_ss) const; + public: bool open(const char* path = "", char mode = 'r', int volume = 0); bool close(); @@ -541,7 +551,7 @@ long TForm770::trasfer(long codditta, TTrasferimento770& file, } TForm770::TForm770(const char* name) -: TForm(name), _sortedcur(NULL) + : TForm(name), _sortedcur(NULL) { const char* key = NULL; @@ -627,7 +637,7 @@ void TTracciato770::auto_fill(TString& buffer) const TTracciato770::TTracciato770(char tipo) : _tipo(tipo) { - if (strchr("ABEHZ", tipo) == NULL) + if (strchr("ABEHJZ", tipo) == NULL) NFCHECK("Tipo record non valido: %c", tipo); add_field("Tipo record", 'A', 1, 1); // 1 @@ -657,8 +667,8 @@ TTracciato770::TTracciato770(char tipo) : _tipo(tipo) // Tipo di dichiarazione add_field("Dichiarazione correttiva nei termini", 'N', 91, 1); // 9 add_filler( 92, 1); - add_field("Dichiarazione integrativa", 'N', 94, 1); - add_field("Eventi eccezzziunali veramente", 'N',102, 2); // 12 + add_field("Dichiarazione integrativa", 'N', 93, 1); + add_field("Eventi eccezzziunali veramente", 'N', 94, 1); // 12 // Dati del contribuente add_field("Cognome", 'A', 95, 24); // 13 @@ -668,59 +678,60 @@ TTracciato770::TTracciato770(char tipo) : _tipo(tipo) add_filler(210, 1); add_filler(211, 1); - add_field("Codice Attivitą", 'N', 212, 5); // 19 + add_field("Codice Attivitą", 'N', 212, 6); // 19 - add_field("Natura giuridica", 'N', 486, 2, 33); // 33 - add_field("Data variazione sede legale", 'D', 488, 6); - add_field("Comune della sede legale", 'A', 494,40); - add_field("Sigla della provincia sede legale", 'A', 534, 2); - add_field("Indirizzo della sede legale", 'A', 536,35); - add_field("CAP del comune della sede legale", 'A', 571, 5); - add_field("Codice comune", 'A', 576, 4); - add_field("Data variazione domicilio fiscale", 'N', 580, 6); // 40 - add_field("Comune del domicilio fiscale", 'A', 586,40); - add_field("Provincia del domicilio fiscale", 'A', 626, 2); - add_field("Indirizzo del domicilio fiscale", 'A', 628,35); - add_field("CAP del domicilio fiscale", 'N', 663, 5); - add_field("Codice comune", 'A', 668, 5); - add_field("Stato", 'N', 672, 1); - add_field("Situazione", 'N', 673, 1); + add_field("Natura giuridica", 'N', 487, 2, 33); // 33 + add_field("Data variazione sede legale", 'D', 489, 6); + add_field("Comune della sede legale", 'A', 495,40); + add_field("Sigla della provincia sede legale", 'A', 535, 2); + add_field("CAP del comune della sede legale", 'A', 537, 5); + add_field("Codice comune", 'A', 542, 4); + add_field("Indirizzo della sede legale", 'A', 546,35); + add_field("Data variazione domicilio fiscale", 'N', 581, 6); // 40 + add_field("Comune del domicilio fiscale", 'A', 587,40); + add_field("Provincia del domicilio fiscale", 'A', 627, 2); + add_field("CAP del domicilio fiscale", 'N', 629, 5); + add_field("Codice comune", 'A', 634, 5); + add_field("Indirizzo del domicilio fiscale", 'A', 638,35); + add_field("Stato", 'N', 673, 1); + add_field("Situazione", 'N', 674, 1); - add_field("Firma del dichiarante", 'N', 760, 1, 54); // 54 + add_field("Firma del dichiarante", 'N', 761, 1, 54); // 54 - add_field("Redazione della dichiarazione", 'N', 796, 1, 75); // 75 + add_field("Redazione della dichiarazione", 'N', 796, 1, 74); // 74 add_field("Numero comunicaz. lavoro dipendente", 'N', 797, 8); add_field("Numero comunicaz. lavoro autonomo", 'N', 805, 8); - add_field("Casella prospetto ST", 'N', 813, 1); - add_field("Casella prospetto SX", 'N', 814, 1); + add_field("Casella prospetto SS", 'N', 813, 1); + add_field("Casella prospetto ST", 'N', 814, 1); + add_field("Casella prospetto SX", 'N', 815, 1); - add_field("Codice fiscale", 'C',1030,16, 89); // 89 - add_field("Denominazione (Alternativo a 91 e 92)",'A',1046,60); - add_field("Cognome", 'A',1106,24); - add_field("Nome", 'A',1130,20); - add_field("Comune", 'A',1150,40); - add_field("Provincia", 'A',1190, 2); - add_field("Codice comune", 'A',1192, 4); - add_field("Cap comune", 'A',1196, 5); - add_field("Tipologia", 'A',1201,15); - add_field("Indirizzo", 'A',1216,35); - add_field("Numero Civico", 'A',1251,10); // 99 + add_field("Codice fiscale", 'C',1030,16, 90); // 90 + add_field("Denominazione (Alternativo a 91 e 92)",'A',1036,60); + add_field("Cognome", 'A',1096,24); + add_field("Nome", 'A',1120,20); + add_field("Comune", 'A',1140,40); + add_field("Provincia", 'A',1180, 2); + add_field("Codice comune", 'A',1182, 4); + add_field("Cap comune", 'A',1186, 5); + add_field("Tipologia", 'A',1191,15); + add_field("Indirizzo", 'A',1206,35); + add_field("Numero Civico", 'A',1241,10); // 100 - add_field("Codice fiscale del rappresentante", 'C',1406,16, 106); // 106 - add_field("Codice carica del rappresentante", 'N',1422, 2); - add_field("Data carica del rappresentante", 'D',1424, 8); - add_filler(1432, 11); - add_field("Denominazione (Alternat. a 111 e 112)",'A',1443,60); // 110 - add_field("Cognome", 'A',1503,24); - add_field("Nome", 'A',1527,20); - add_field("Sesso", 'A',1547, 1); - add_field("Data di nascita", 'N',1548, 8); - add_field("Comune di nascita", 'A',1556,40); // 115 - add_field("Provincia di nascita", 'A',1596, 2); - add_field("Comune residenza", 'A',1598,40); - add_field("Provincia residenza", 'A',1638, 2); - add_field("Cap residenza", 'N',1640, 5); - add_field("Indirizzo residenza", 'A',1645,35); // 120 + add_field("Codice fiscale del rappresentante", 'C',1396,16,107); // 107 + add_field("Codice carica del rappresentante", 'N',1412, 2); + add_field("Data carica del rappresentante", 'D',1414, 8); + add_filler(1422, 11); + add_field("Denominazione (Alternativo a 112-117)",'A',1433,60,111); // 111 + add_field("Cognome", 'A',1493,24); + add_field("Nome", 'A',1517,20); + add_field("Sesso", 'A',1537, 1); + add_field("Data di nascita", 'D',1538, 8); + add_field("Comune di nascita", 'A',1546,40); // 116 + add_field("Provincia di nascita", 'A',1586, 2); + add_field("Comune residenza", 'A',1588,40); + add_field("Provincia residenza", 'A',1628, 2); + add_field("Cap residenza", 'N',1630, 5); + add_field("Indirizzo residenza", 'A',1635,35); // 121 } else if (tipo == 'E') @@ -744,6 +755,16 @@ TTracciato770::TTracciato770(char tipo) : _tipo(tipo) add_field("Spazio a disposizione", 'A', 54, 20); add_field("Codice fiscale della software house", 'A', 74, 16); // 9 } else + if (tipo == 'J') + { + add_field("Codice fiscale del dichiarante", 'C', 2, 16); // 2 + add_field("Progressivo modulo", 'N', 18, 8); + add_field("Spazio a disposizione", 'A', 26, 3); + add_field("Tipo operazione", 'A', 29, 1); + add_filler(30, 24); + add_field("Spazio a disposizione", 'A', 54, 20); + add_field("Codice fiscale della software house", 'A', 74, 16); // 8 + } else if (tipo == 'Z') { add_filler(2, 14); // 2 @@ -752,6 +773,7 @@ TTracciato770::TTracciato770(char tipo) : _tipo(tipo) add_field("Numero record di tipo 'F'", 'N', 34, 9); add_field("Numero record di tipo 'G'", 'N', 43, 9); // 6 add_field("Numero record di tipo 'H'", 'N', 52, 9); + add_field("Numero record di tipo 'J'", 'N', 61, 9); add_filler(61, 1837); } } @@ -986,8 +1008,7 @@ bool TRecord770::add(const char* code, const char* val) CHECKS(val && *val, "Can't add empty field ", code); // Cerca il primo posto libero - int pos; - for (pos = HEADER_SIZE; pos < HEADER_SIZE+USEABLE_SIZE; pos += BLOCK_SIZE) + for (int pos = HEADER_SIZE; pos < HEADER_SIZE+USEABLE_SIZE; pos += BLOCK_SIZE) { if (_buffer[pos] == ' ') break; @@ -1020,10 +1041,43 @@ bool TRecord770::add(const char* code, const char* val) return ok; } +bool TRecord770::add(const char* code, const real& val) +{ + return add(code, val.string(16, 0)); +} + +bool TRecord770::np_get(int pos, TString& key, TString& val) const +{ + CHECK(ha_campi_non_posizionali(), "Impossibile leggere campi non posizionali"); + const int n = HEADER_SIZE + pos * BLOCK_SIZE; + bool ok = false; + if (n < HEADER_SIZE + USEABLE_SIZE) + { + ok = _buffer[n] > ' '; + if (ok) + { + key = _buffer.mid(n, CODE_SIZE); + val = _buffer.mid(n+CODE_SIZE, FIELD_SIZE); + } + } + return ok; +} + +bool TRecord770::np_get_real(int pos, TString& key, real& val) const +{ + TString16 str; + const bool ok = np_get(pos, key, str); + if (ok) + val = real(str); + else + val = ZERO; + return ok; +} + bool TRecord770::valid() const { char tipo = tipo_record(); - bool ok = (tipo > ' ') && (strchr("ABEHZ", tipo) != NULL); + bool ok = (tipo > ' ') && (strchr("ABEHJZ", tipo) != NULL); return ok; } @@ -1070,7 +1124,7 @@ bool TTrasferimento770::open(const char* path, char mode, int volume) _name << '_' << volume; } if (mode == 'r') - _in_stream = new ifstream(_name, ios::in | ios::binary); + _in_stream = new ifstream(_name, ios::in | ios::nocreate | ios::binary); else _out_stream = new ofstream(_name, ios::out | ios::binary); @@ -1113,7 +1167,7 @@ bool TTrasferimento770::read(TRecord770& rec) const TString& TTrasferimento770::read_codfis_dic(const TRectype& rec) { - TString80 key; // Stringa multiuso + TToken_string key; // Stringa multiuso key = rec.get(BSE_CODDIC); if (key.empty()) @@ -1122,20 +1176,29 @@ const TString& TTrasferimento770::read_codfis_dic(const TRectype& rec) const TRectype& rec_nditte = _cache770.get(LF_NDITTE, key); if (rec_nditte.empty()) { - error_box("Non esiste la ditta %s", (const char*)key); + error_box(FR("Non esiste la ditta %s"), (const char*)key); return EMPTY_STRING; } _cod_ditta = atol(key); - _codatt_dic = rec_nditte.get(NDT_CODATTPREV); // Codice attivita' prevalente _tipoa_dic = rec_nditte.get_char(NDT_TIPOA); _codan_dic = rec_nditte.get_long(NDT_CODANAGR); - key.cut(0); - key << _tipoa_dic << '|' << rec_nditte.get(NDT_CODANAGR); + _codatt_dic = rec_nditte.get(NDT_CODATTPREV); // Codice attivita' prevalente + key.add(_codatt_dic); // key = CODDITTA|CODATTPREV + const TRectype& attiv = _cache770.get(LF_ATTIV, key); + if (attiv.exist(ATT_CODATECO)) // Non e' detto che il campo esista sempre + { + const TString& codateco = attiv.get(ATT_CODATECO); + if (codateco.full()) + _codatt_dic = codateco; + } + + key.cut(0) << _tipoa_dic; + key.add(rec_nditte.get(NDT_CODANAGR)); const TRectype& rec_anagr = _cache770.get(LF_ANAG, key); if (rec_anagr.empty()) { - error_box("Non esiste la persona %s", (const char*)key); + error_box(FR("Non esiste la persona %s"), (const char*)key); return EMPTY_STRING; } _codfis_dic = rec_anagr.get(ANA_COFI); // Codice fiscale del dichiarante @@ -1204,38 +1267,44 @@ bool TTrasferimento770::append_record_b() rec.set(36, rec_comres.get(COM_PROVCOM)); TString indirizzo; indirizzo << rec_anagr.get(ANA_INDRES) << ' ' << rec_anagr.get(ANA_CIVRES); - indirizzo.strip_double_spaces(); indirizzo.cut(35); - rec.set(37, indirizzo); - rec.set(38, rec_anagr.get(ANA_CAPRES)); - rec.set(39, rec_anagr.get(ANA_COMRES)); + indirizzo.strip_d_spaces(); indirizzo.cut(35); + rec.set(37, rec_anagr.get(ANA_CAPRES)); + rec.set(38, rec_anagr.get(ANA_COMRES)); + rec.set(39, indirizzo); rec.set(46, rec_anagiu.get(ANG_STATOSOC)); rec.set(47, rec_anagiu.get(ANG_SITSOC)); } - rec.set(75, 1); - rec.set(76, 0); - rec.set(77, conta_certificazioni()); + rec.set(74, 1); + rec.set(75, 0); + const int autonomi = conta_certificazioni(); + rec.set(76, autonomi); + rec.set(77, autonomi > 0); // casella prospetto SS rec.set(78, casella_prospetto_st()); rec.set(79, casella_prospetto_sx()); - rec.set(89, cod_fis_dic()); - rec.set(90, _ragsoc_dic); - rec.set(93, rec_comres.get(COM_DENCOM)); - rec.set(94, rec_comres.get(COM_PROVCOM)); - rec.set(95, rec_anagr.get(ANA_COMRES)); - rec.set(96, rec_anagr.get(ANA_CAPRES)); + rec.set(90, cod_fis_dic()); + rec.set(91, _ragsoc_dic); + rec.set(94, rec_comres.get(COM_DENCOM)); + rec.set(95, rec_comres.get(COM_PROVCOM)); + rec.set(96, rec_anagr.get(ANA_COMRES)); + rec.set(97, rec_anagr.get(ANA_CAPRES)); TString80 indirizzo = rec_anagr.get(ANA_INDRES); - indirizzo.strip_double_spaces(); indirizzo.trim(); + indirizzo.strip_d_spaces(); indirizzo.trim(); TString8 tipologia; const int spazio = indirizzo.find(' '); - if (spazio > 0 && spazio < 16) + if (spazio > 0 && spazio < 16) // Lunghezza accettabile per TString16 successiva { TString16 t = indirizzo.left(spazio); t.trim(); t.upper(); + if (t == "C.LE" || t == "CALLE") tipologia = "CALLE"; else + if (t == "C.SO" || t == "CORSO") tipologia = "CORSO"; else if (t == "L.GO" || t == "LARGO") tipologia = "LARGO"; else + if (t == "P.CO" || t == "PARCO") tipologia = "PARCO"; else if (t == "P.ZA" || t == "PIAZZA") tipologia = "PIAZZA"; else + if (t == "S.DA" || t == "STRADA") tipologia = "STRADA"; else if (t == "V." || t == "VIA") tipologia = "VIA"; else if (t == "V.LE" || t == "VIALE") tipologia = "VIALE"; else if (t == "V.LO" || t == "VICOLO") tipologia = "VICOLO"; @@ -1246,9 +1315,9 @@ bool TTrasferimento770::append_record_b() tipologia = "VIA"; indirizzo.cut(35); - rec.set(97, tipologia); - rec.set(98, indirizzo); - rec.set(99, rec_anagr.get(ANA_CIVRES)); + rec.set(98, tipologia); + rec.set(99, indirizzo); + rec.set(100, rec_anagr.get(ANA_CIVRES)); const TRectype& rec_nditte = _cache770.get(LF_NDITTE, _cod_ditta); @@ -1259,21 +1328,21 @@ bool TTrasferimento770::append_record_b() const TRectype& rec_com_nas = _cache770.get(LF_COMUNI, key); key.cut(0) << "|" << rec_rap.get(ANA_COMRES); const TRectype& rec_com_res = _cache770.get(LF_COMUNI, key); - rec.set(106, rec_rap.get(ANA_COFI)); - rec.set(107, rec_nditte.get(NDT_CARRAPP)); + rec.set(107, rec_rap.get(ANA_COFI)); + rec.set(108, rec_nditte.get(NDT_CARRAPP)); rec.set(111, rec_rap.get(ANA_RAGSOC).left(24)); rec.set(112, rec_rap.get(ANA_RAGSOC).mid(30, 20)); - rec.set(113, rec_rap_fis.get(ANF_SESSO)); - rec.set(114, rec_rap_fis.get_date(ANF_DATANASC)); - rec.set(115, rec_com_nas.get(COM_DENCOM)); - rec.set(116, rec_com_nas.get(COM_PROVCOM)); - rec.set(117, rec_com_res.get(COM_DENCOM)); - rec.set(118, rec_com_res.get(COM_PROVCOM)); - rec.set(119, rec_rap.get(ANA_CAPRES)); + rec.set(114, rec_rap_fis.get(ANF_SESSO)); + rec.set(115, rec_rap_fis.get_date(ANF_DATANASC)); + rec.set(116, rec_com_nas.get(COM_DENCOM)); + rec.set(117, rec_com_nas.get(COM_PROVCOM)); + rec.set(118, rec_com_res.get(COM_DENCOM)); + rec.set(119, rec_com_res.get(COM_PROVCOM)); + rec.set(120, rec_rap.get(ANA_CAPRES)); indirizzo.cut(0); indirizzo << rec_rap.get(ANA_INDRES) << ' ' << rec_rap.get(ANA_CIVRES); - indirizzo.strip_double_spaces(); indirizzo.cut(35); indirizzo.trim(); - rec.set(120, indirizzo); + indirizzo.strip_d_spaces(); indirizzo.cut(35); indirizzo.trim(); + rec.set(121, indirizzo); ok = write(rec); } @@ -1283,7 +1352,7 @@ bool TTrasferimento770::append_record_b() long TTrasferimento770::append_quadro(const char* quadro, long codditta, TProgind& pi) { TString str; - str << "Trasferimento quadro " << quadro << " ditta " << codditta; + str << TR("Trasferimento quadro ") << quadro << TR(" ditta ") << codditta; pi.set_text(str); char tipo; @@ -1293,12 +1362,34 @@ long TTrasferimento770::append_quadro(const char* quadro, long codditta, TProgin return items; } +void TTrasferimento770::riepiloga_ss(const TRecord770& rec, TArray& riep_ss) const +{ + TString8 code; + real val; + for (int i = 0; rec.np_get_real(i, code, val); i++) if (code.starts_with("AU")) + { + const TString& key = code.right(3); + const int num = atoi(key); + if (num >= 25 && num <= 30) + { + const int idx = num-25; + real* r = (real*)riep_ss.objptr(idx); + if (r == NULL) + { + r = new real; + riep_ss.add(r, idx); + } + *r += val; + } + } +} + bool TTrasferimento770::split(const char* path) { close(); const long records = fsize(_name) / TOTAL_SIZE; - long totale[26]; memset(totale, 0, sizeof(totale)); + TRecnotype totale[26]; memset(totale, 0, sizeof(totale)); TRecord770 rec; @@ -1342,7 +1433,7 @@ bool TTrasferimento770::split(const char* path) // Compila record di testata A rec.tipo_record('A'); - rec.set(3, "77S07"); + rec.set(3, "77S08"); rec.set(4, 1); // 01 = Soggetto che invia la propria dichiarazione rec.set(5, cod_fis_dic()); if (volumes > 1) @@ -1361,6 +1452,8 @@ bool TTrasferimento770::split(const char* path) long written = 0; + TArray riep_ss; + if (records > 0) { while (read(rec)) @@ -1368,13 +1461,20 @@ bool TTrasferimento770::split(const char* path) pi.addstatus(1); const char tipo_rec = rec.tipo_record(); - if (tipo_rec <= 'A' || tipo_rec >= 'Z') + if (tipo_rec <= 'A' || tipo_rec == 'J' || tipo_rec >= 'Z') continue; outfile << rec; - totale[tipo_rec - 'A']++; written++; + if (_save_headers) + { + totale[tipo_rec - 'A']++; + + if (tipo_rec == 'H') + riepiloga_ss(rec, riep_ss); + } + if (written >= records_per_disk) break; } @@ -1382,6 +1482,27 @@ bool TTrasferimento770::split(const char* path) if (_save_headers) { + // Compila record di riepilogo SS + if (riep_ss.items() > 0) + { + rec.tipo_record('J'); + rec.set(2, cod_fis_dic()); + rec.set(3, 1); + rec.set(8, CF_PRODUTTORE); + FOR_EACH_ARRAY_ITEM(riep_ss, i, obj) + { + const real* val = (const real*)obj; + if (val != NULL) + { + TString8 code; + code.format("SS003%03d", i+1); // i=0 -> SS0003001 -> AUXXX025 + rec.add(code, *val); + } + } + outfile << rec; + totale['J' - 'A']++; // Praticamente vale sempre 1 + } + // Compila record di coda rec.tipo_record('Z'); rec.set(3, totale['B'-'A']); // Totale B @@ -1389,6 +1510,7 @@ bool TTrasferimento770::split(const char* path) rec.set(5, totale['F'-'A']); // Totale F rec.set(6, totale['G'-'A']); // Totale G rec.set(7, totale['H'-'A']); // Totale H + rec.set(8, totale['J'-'A']); // Totale J // Scrive record di coda outfile << rec; @@ -1473,11 +1595,11 @@ void TTransfer770_app::main_loop() da_rec.put(BSE_CODDITTA, m.get(F_DADITTA)); a_rec.put(BSE_CODDITTA, m.get(F_ADITTA)); - TString filter; - filter << BSE_ANNODIC << '=' << anno_dic(); + TString16 filter; + filter << BSE_ANNODIC << '=' << m.get(F_ANNO); TCursor cur_base(&rel_base, filter, 1, &da_rec, &a_rec); - TProgind pi(cur_base.items(), "Generazione file di trasferimento", false, true); + TProgind pi(cur_base.items(), TR("Generazione file di trasferimento"), false, true); cur_base.freeze(); TRecord770 rec; // Record di lavoro diff --git a/m770/777200.cpp b/m770/777200.cpp index e534a6b74..0e5c02733 100755 --- a/m770/777200.cpp +++ b/m770/777200.cpp @@ -1,5 +1,3 @@ -#include - #include #include #include @@ -562,7 +560,7 @@ bool TTrasferimentoDylog::open(const char* path, char mode) if (_name.empty()) _name = default_name(); if (mode == 'r') - _in_stream = new ifstream(_name, ios::in | ios::binary); + _in_stream = new ifstream(_name, ios::in | ios::nocreate | ios::binary); else _out_stream = new ofstream(_name, ios::out | ios::binary); diff --git a/mg/mg3600.cpp b/mg/mg3600.cpp index 85f96e098..621a310ba 100755 --- a/mg/mg3600.cpp +++ b/mg/mg3600.cpp @@ -68,10 +68,24 @@ void TStampa_etich_art_recordset::set_filter(const TStampa_etich_art_mask& msk) { TVariant var; - var = msk.get(F_DACODART); - set_var("#DACODART", var); - var = msk.get(F_ACODART); - set_var("#ACODART", var); + //carica TUTTI i valori nel recordset dalla maschera + const int items=msk.fields(); + for (short i=0; iname(); + //aggiungo "#" all'inizio della stringa dove manca + if (!fldname.starts_with("#")) + fldname.insert("#"); + var=f.get(); + set_var(fldname,var); + } + } + _ncopie = msk.get_int(F_QTA); } @@ -127,17 +141,23 @@ void TStampa_etich_mov_recordset::set_filter(const TStampa_etich_art_mask& msk) { TVariant var; - var = msk.get(F_DACODART); - set_var("#DACODART", var); - var = msk.get(F_ACODART); - set_var("#ACODART", var); - var = msk.get(F_DADATA); - set_var("#DADATA", var); - var = msk.get(F_ADATA); - set_var("#ADATA", var); - var = msk.get(F_CAUS); - set_var("#CAUS", var); - TCursor * c = cursor(); + const int items=msk.fields(); + for (short i=0; iname(); + if (!fldname.starts_with("#")) + fldname.insert("#"); + var=f.get(); + set_var(fldname,var); + } + } + + TCursor * c = cursor(); requery(); } @@ -270,6 +290,7 @@ void TStampa_etich_art::main_loop() rep.load("mg3600a"); rep.set_filter(mask); book.add(rep); + book.print_or_preview(); //stampa il book dei report } else { @@ -278,8 +299,9 @@ void TStampa_etich_art::main_loop() rep.load("mg3600b"); rep.set_filter(mask); book.add(rep); + book.print_or_preview(); //stampa il book dei report } - book.print_or_preview(); //stampa il book dei report + } } diff --git a/mg/mgmenu.men b/mg/mgmenu.men index 442201bc7..375eaa07b 100755 --- a/mg/mgmenu.men +++ b/mg/mgmenu.men @@ -40,6 +40,7 @@ Item_05 = "Inventario", "mg4 -1", "F" Item_06 = "Libro giornale", "mg4 -2", "F" Item_07 = "Lista movimenti", "mg4 -0", "F" Item_08 = "Storico rimanenze", "mg3 -4", "F" +Item_09 = "Etichette", "mg3 -5", "F" [MGMENU_070] Caption = "Servizi modulo magazzino" diff --git a/mr/mr0100.cpp b/mr/mr0100.cpp index 02ad72f6e..774d71cba 100755 --- a/mr/mr0100.cpp +++ b/mr/mr0100.cpp @@ -215,12 +215,12 @@ void TMRPtables::read_turni(TMask& m) TUnita_produttiva up(file().curr()); for (int t = 7; t >= 0; t--) { - const int id = F_T1HINIZIO+t*5; - m.set(id, up.ora_inizio_turno(t)); - m.set(id+1, up.min_inizio_turno(t)); - m.set(id+2, up.ore_durata_turno(t)); - m.set(id+3, up.min_durata_turno(t)); - m.set(id+4, up.raw_numpers_turno(t)); + const short id = F_T1HINIZIO+t*5; + m.set(id,up.ora_inizio_turno(t)); + m.set(id+1,up.min_inizio_turno(t)); + m.set(id+2,up.ore_durata_turno(t)); + m.set(id+3,up.min_durata_turno(t)); + m.set(id+4,up.raw_numpers_turno(t));; } } @@ -229,7 +229,7 @@ void TMRPtables::write_turni(const TMask& m) TUnita_produttiva up(file().curr()); for (int t=0; t < 8; t++) { - const int id = F_T1HINIZIO+t*5; + const short id = F_T1HINIZIO+t*5; up.set_inizio_turno(t, m.get_int(id), m.get_int(id+1)); up.set_durata_turno(t, m.get_int(id+2), m.get_int(id+3)); up.set_numpers_turno(t, m.get_int(id+4)); diff --git a/mr/mr2200.cpp b/mr/mr2200.cpp index 064d5c1e0..12f4f1ce8 100755 --- a/mr/mr2200.cpp +++ b/mr/mr2200.cpp @@ -528,6 +528,19 @@ bool TPlanning_mask::carica_documenti() const int year_fr = date_fr.year() - (get_bool(F_DOC_YEAR_PREC) ? 1 : 0); const int year_to = date_to.year(); + TDate datalim(date_fr); + const int days = days_per_bucket(); + + if (days < 7 ) + datalim -= 7; + else + if (days < 31) + datalim.addmonth(-1); + else + if (days < 180) + datalim.addmonth(-3); + else + datalim -= days * 2; TTable num("%NUM"); TCodice_numerazione cod; @@ -587,9 +600,13 @@ bool TPlanning_mask::carica_documenti() continue; const bool ignore_prec = get_bool(F_IGNORE_PREC); - if (ignore_prec && (tn & _Doc_planning) && (datacons < date_fr)) - continue; +// if (ignore_prec && (tn & _Doc_planning) && (datacons < date_fr)) +// continue; + const bool skip = ignore_prec && (tn & _Doc_planning) && (datacons < date_fr); + if (skip) + if (datacons < datalim) + continue; // Scandisce le righe articolo e memorizza // le quantita' richieste const TDocumento doc(cur.curr()); @@ -656,6 +673,7 @@ bool TPlanning_mask::carica_documenti() if (buck > LAST_BUCKET) buck = LAST_BUCKET; TMSP_constraint* line = NULL; + if (tn & _Doc_vincoli) { line = _constraints.find(cli, art, liv, imp, lin, mag, magc, da_rdoc_key, true); @@ -729,10 +747,12 @@ bool TPlanning_mask::carica_documenti() } } } - if (p > line->priority()) - line->priority(p); + if (p > line->priority()) + line->priority(p); } + if (!skip) + { if (tn & _Doc_planning) { // controlla lo stato definitivo dei documenti @@ -742,11 +762,18 @@ bool TPlanning_mask::carica_documenti() { //line->qta_locked(buck) = true; line->qta_min(buck) += q.val(); - } else { + } + else + { //add_MRP_bucket(*find_propose(cli, art, liv, imp, lin, mag, magc, true), buck, q.val()); } } line->qta(buck) += q.val(); + } +// else +// if (art == "008BTN003013CAON") +// int i = 1; + real price; find_price(get(F_TIPOCV),get(F_CODCONDV),get(F_CATVEN_CV), get(F_TIPOCF), cli, art, line->qta(buck), price); @@ -1659,7 +1686,8 @@ void TPlanning_mask::review_cell(long mrp_row, int bucket, bool check_machine, b add_MRP_bucket(*new_article, nbucket, curr_arts); } } - } else + } + else error_box("Articolo %s: impianto %s incompatibile con la linea %s",(const char *)mrpline.articolo(), (const char *)codimp, (const char *)linea_prod.codice()); if ((logic == _uniform_logic) || (logic == _first_fit_logic && firstfitxbucket)) @@ -2308,7 +2336,7 @@ bool TPlanning_mask::do_test_art_row(int r, int first, int last, bool signal) TToken_string& giac_row = sf.row(first); // ********** - // setta la priorita' su tutte le righe del blocco + // setta la priorita' e la linea su tutte le righe del blocco TString16 prior = curr_row.get(sf.cid2index(F_PRIORITA)); prior.trim(); TString16 old_prior=constr_row.get(sf.cid2index(F_PRIORITA)); old_prior.trim(); if (prior != old_prior) @@ -2325,6 +2353,9 @@ bool TPlanning_mask::do_test_art_row(int r, int first, int last, bool signal) sf.row(r).add(old_prior, sf.cid2index(F_PRIORITA)); } + TString8 codlin = curr_row.get(sf.cid2index(F_CODLIN)); prior.trim(); + constr_row.add(codlin , sf.cid2index(F_CODLIN)); + sf.force_update(first - 1); // ********** // calcola la giacenza proiettata TCodice_articolo codart(curr_row.get(sf.cid2index(F_ARTICOLO))); @@ -3302,6 +3333,22 @@ bool TPlanning_mask::on_field_event(TOperable_field& o, TField_event e, long jol case F_BUCKET12: case F_BUCKET13: case F_BUCKET14: + case F_BUCKET15: + case F_BUCKET16: + case F_BUCKET17: + case F_BUCKET18: + case F_BUCKET19: + case F_BUCKET20: + case F_BUCKET21: + case F_BUCKET22: + case F_BUCKET23: + case F_BUCKET24: + case F_BUCKET25: + case F_BUCKET26: + case F_BUCKET27: + case F_BUCKET28: + case F_BUCKET29: + case F_BUCKET30: if (e == fe_modify) { const TSheet_field& s = sfield(F_ARTICOLI); diff --git a/mr/mr2201.cpp b/mr/mr2201.cpp index 94adb8303..ec5ac6d85 100755 --- a/mr/mr2201.cpp +++ b/mr/mr2201.cpp @@ -276,7 +276,7 @@ int TRiga_articolo::order_compare( const TToken_string &r1, const TToken_string // aggiunge li codici di linea/impianto se non presenti usando i default sulle lavorazioni critiche // cio' permette di ordinare per impianto anche le linee di ordine che non hanno solitamente // questa indicazione ma solo il codice articolo -void complete_codlinea(TToken_string& r2, bool ignore_imp) +void complete_codlinea(TToken_string &r2, bool ignore_imp) { TString8 codimp; r2.get(F_SORTCODIMP-FIRST_FIELD, codimp); @@ -322,9 +322,8 @@ void complete_codlinea(TToken_string& r2, bool ignore_imp) int TRiga_articolo::order_compare(TSheet_field& s, int i1, int i2, int level) { - const TMask& m = s.mask(); - const bool ascending = !m.get_bool(F_MSP_SORT_ORDER); - + const TMask &m = s.mask(); + const bool ascending=!m.get_bool(F_MSP_SORT_ORDER); int first1 = 0, first2 = 0, last1 = 0, last2 = 0; if (find_block(s, i1, first1, last1 )) first1--; @@ -360,7 +359,7 @@ int TRiga_articolo::order_compare(TSheet_field& s, int i1, int i2, int level) if (line_matters) { - const bool noimpin = m.get_bool(F_NOIMP_IN); + const bool noimpin = m.get_bool(F_NOIMP_IN); complete_codlinea(blockr1, noimpin); complete_codlinea(blockr2, noimpin); @@ -803,6 +802,7 @@ TMSP_line2::TMSP_line2(const TMSP_constraint &c) /////////////////////////////////////////////////////////// // TMSP_constraint /////////////////////////////////////////////////////////// +TString16 TMSP_constraint::_substr; int TMSP_constraint::compare(const TSortable& s) const { const TMSP_constraint& c = (const TMSP_constraint&)s; @@ -858,10 +858,26 @@ void TMSP_constraint::fill_sheet_row(TToken_string& row, const TMask & m, const const TString80 da_rdoc_key(da_rdoc_key()); if (da_rdoc_key.full()) - val << '¦' << da_rdoc_key; + val << ' ' << SAFE_PIPE_CHR << ' ' << da_rdoc_key; - row.add(val, F_DESCART-FIRST_FIELD); - row.add(codimp(),F_CODIMP-FIRST_FIELD); + if ((descr == NULL || *descr == '\0') && __userflds != NULL && __userflds->full()) + { + TString userdesc; + TString16 fldname; + const TRectype & anamag = cache().get(LF_ANAMAG, articolo()); + + for (int n = __userflds->get_int(0); n > 0; n = __userflds->get_int()) + { + fldname.format("USER%d", n); + const TString & fldval = anamag.get(fldname); + + if (fldval.full()) + userdesc << fldval << __sep; + } + userdesc << " "; + val.insert(userdesc); + } + row.add(val, F_DESCART-FIRST_FIELD); row.add(codlin(),F_CODLIN-FIRST_FIELD); //TString8 str = _codmag.left(3); @@ -887,7 +903,7 @@ void TMSP_constraint::fill_sheet_row(TToken_string& row, const TMask & m, const } row.add(mastercodes2check() ? MASTERCODE_CHAR : ' ',F_MASTERCODE-FIRST_FIELD); - // CHECK((_sheet_row == NULL) || (_sheet_row == &row), "TMSP_constraint splitted upon two rows"); +// CHECK((_sheet_row == NULL) || (_sheet_row == &row), "TMSP_constraint splitted upon two rows"); if (_sheet_row == NULL) _sheet_row = &row; } @@ -1132,6 +1148,20 @@ TMSP_constraint & TMSP_constraint::operator=(const TMSP_constraint & line) return *this; } +TToken_string * TMSP_constraint::__userflds = NULL; +char TMSP_constraint::__sep = ';'; + +void TMSP_constraint::init() +{ + if (__userflds == NULL) + { + TConfig c(CONFIG_DITTA, "mr"); + + __userflds = new TToken_string(c.get("USERFLDS")); + if (c.exist("FLDSEP")) + __sep = c.get_char("FLDSEP"); + } +} TMSP_constraint::TMSP_constraint(long cliente, const TCodice_articolo& codart, @@ -1144,14 +1174,18 @@ TMSP_constraint::TMSP_constraint(long cliente, : _codclifor(cliente), _codart(codart), _livgiac(giac), _codimp(imp), _codlin(lin), _codmag(mag), _codmag_coll(magc), _da_rdoc_key(da_rdoc_key),_on_sheet(false),_check_master(false), _upperlines(NULL), _lines2(NULL), _priority(0), _sheet_row(NULL) -{ } +{ + init(); +} TMSP_constraint::TMSP_constraint(const TMSP_constraint & line) : _codclifor(line.codclifor()), _codart(line.articolo()), _livgiac(line.livgiac()), _codimp(line.codimp()), _codlin(line.codlin()), _codmag(line.codmagdep()), _codmag_coll(line.codmagdep_coll()), _da_rdoc_key(line.da_rdoc_key()), _descr(line.description()), _on_sheet(false), _check_master(false), _upperlines(NULL), _lines2(NULL), _priority(0), _sheet_row(NULL) -{ } +{ + init(); +} TMSP_constraint::~TMSP_constraint() { @@ -1251,7 +1285,7 @@ TMSP_constraint* TMSP_constraints::find(const TToken_string& row, bool create) _key << str; _key.strip_spaces(); row.get(F_DESCART-FIRST_FIELD, str); - const int pos = str.find('¦'); + const int pos = str.find(SAFE_PIPE_CHR); if (pos >= 0) _key.add(str.mid(pos +1)); @@ -1382,7 +1416,7 @@ TMSP_line* TMSP_lines::find(const TToken_string& row, bool create) } } row.get(F_DESCART-FIRST_FIELD, str); - const int pos = str.find('¦'); + const int pos = str.find(SAFE_PIPE_CHR); if (pos >= 0) _key.add(str.mid(pos +1)); @@ -1608,7 +1642,7 @@ void TLista_dettagli::init(const char * title, const TDate& fromdate, int bucket _curr_bucket = -1; _from = fromdate; _bucksize = bucketsize; - TMask_field &f= add_list(FIRST_FIELD,0,"Bucket ",1,0,2,"","0|1|2|3|4|5|6|7|8|9|10|11|12|13","0|1|2|3|4|5|6|7|8|9|10|11|12|13"); + TMask_field &f= add_list(FIRST_FIELD,0,"Bucket ",1,0,2,"","0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30","0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30"); f.set_handler(bucket_handler); add_date(FIRST_FIELD+1,0,TR("Dal "),16,0,"D"); add_date(FIRST_FIELD+2,0,TR("al "),33,0,"D"); @@ -1673,10 +1707,10 @@ bool TLista_docref::edit_checked() action.set("Action","MODIFY","Transaction"); action.set_paragraph(format("%d",LF_DOC)); TToken_string & rw = row(r); - action.set("PROVV","D"); - action.set("ANNODOC",rw.get(1)); - action.set("CODNUM",rw.get(2)); - action.set("NDOC",rw.get(3)); + action.set(DOC_PROVV,"D"); + action.set(DOC_ANNO,rw.get(1)); + action.set(DOC_CODNUM,rw.get(2)); + action.set(DOC_NDOC,rw.get(3)); } TExternal_app editdoc(format("VE0 -1 -i%s",(const char *)ininame)); editdoc.run(); @@ -1773,7 +1807,7 @@ const char *TLista_upperlines::header() } TLista_upperlines::TLista_upperlines(TMSP_constraint *l, TDate fromdate, int bucketsize): - TLista_dettagli(TR("Vincoli da articoli non Master"), fromdate, bucketsize,header()) + TLista_dettagli(TR("Vincoli da articoli non Master"), fromdate, bucketsize,header()) { _line = l; } diff --git a/mr/mr2201.h b/mr/mr2201.h index ce57d00a2..f46098b3d 100755 --- a/mr/mr2201.h +++ b/mr/mr2201.h @@ -199,11 +199,15 @@ class TMSP_constraint : public TSortable TMSP_record_array _bucket_qta; // pianificazione const TToken_string* _sheet_row; + static TString16 _substr; + static TToken_string * __userflds; + static char __sep; + protected: virtual int compare(const TSortable& s) const; public: - const char* um(); + const char *um(); long codclifor() const { return _codclifor; } const TCodice_articolo& articolo() const { return _codart; } const TString& livgiac() const { return _livgiac; } @@ -215,11 +219,11 @@ public: const TString& description() const { return _descr; } void set_description(const char* str) { _descr = str; } - const TString& codmag() const { return _codmag.left(3); } - const TString& coddep() const { return _codmag.mid(3); } - const TString& codmag_coll() const { return _codmag_coll.left(3); } - const TString& coddep_coll() const { return _codmag_coll.mid(3); } - const TString& livgiac(int l) const { return _livgiac.mid(livelli_giacenza().code_start(l)-1, livelli_giacenza().code_length(l));} + const TString& codmag() const { return _substr = _codmag.left(3); } + const TString& coddep() const { return _substr = _codmag.mid(3); } + const TString& codmag_coll() const { return _substr = _codmag_coll.left(3); } + const TString& coddep_coll() const { return _substr = _codmag_coll.mid(3); } + const TString& livgiac(int l) const { return _substr = _livgiac.mid(livelli_giacenza().code_start(l)-1, livelli_giacenza().code_length(l));} TMRP_docref * first_rigaref(int buck); TMRP_docref * next_rigaref(int buck); @@ -262,6 +266,7 @@ public: bool is_on_sheet() const { return _on_sheet; } void set_on_sheet(bool on = TRUE) { _on_sheet = on; } const TToken_string* sheet_row_ptr() const { return _sheet_row; } + void init(); TMSP_constraint & operator=(const TMSP_constraint & line); diff --git a/or/or1.cpp b/or/or1.cpp index 48df3fa22..bf316eb00 100755 --- a/or/or1.cpp +++ b/or/or1.cpp @@ -16,8 +16,10 @@ int main(int argc,char** argv) or1200(argc,argv); break; // stampa dettaglio disponibilita' articoli case 2: or1300(argc,argv); break; // stampa statistiche sui tempi di consegna + case 3: + or1400(argc,argv); break; // generazione orini a fornitore default: - error_box(TR("Errore - uso : %s -{0|1|2}"), argv[0]); + error_box(TR("Errore - uso : %s -{0|1|2|3}"), argv[0]); } exit(0); return 0; diff --git a/or/or1.h b/or/or1.h index 9fe662391..3d68ee1bb 100755 --- a/or/or1.h +++ b/or/or1.h @@ -4,6 +4,7 @@ int or1100(int argc, char** argv); int or1200(int argc, char** argv); int or1300(int argc, char** argv); +int or1400(int argc, char** argv); #endif // __OR1_H diff --git a/or/or1400.cpp b/or/or1400.cpp new file mode 100755 index 000000000..83b65c4ce --- /dev/null +++ b/or/or1400.cpp @@ -0,0 +1,545 @@ +// Stampa dettaglio disponibilita' articoli +#include +#include +#include +#include +#include +#include + +#include "orlib.h" +#include "or1400a.h" + +#include "../cg/cglib01.h" +#include "../mg/mglib.h" +#include "../ve/velib.h" +#include "../mg/anamag.h" +#include +#include + +static int __codes; + +class TArticoli_recordset : public TISAM_recordset +{ + bool _sottoscorta; + +protected: + static bool filtra_sottoscorta(const TRelation* rel); + +public: + virtual TCursor* cursor() const; + TArticoli_recordset(const char* use, bool sottoscorta, int codes) : TISAM_recordset(use), _sottoscorta(sottoscorta) { __codes = codes; } + virtual ~TArticoli_recordset() {} +}; + +bool TArticoli_recordset::filtra_sottoscorta(const TRelation* rel) +{ + ((TRelation *)rel)->save_status(); + const TString codart = rel->curr(LF_ANAMAG).get(ANAMAG_CODART); + TArticolo_giacenza artgiac(codart); + + const real giac = artgiac.giacenza_anno(NULL, NULL, __codes); + + const bool ok = giac < artgiac.scorta_minima(NULL, NULL, __codes); + ((TRelation *)rel)->restore_status(); + return ok; +} + +TCursor* TArticoli_recordset::cursor() const +{ + TCursor * c = TISAM_recordset::cursor(); + + if (c != NULL && _sottoscorta) + c->set_filterfunction(filtra_sottoscorta); + return c; +} + +class TGenera_ordini_mask : public TAutomask +{ + TString _anamag_query; + bool _filter_changed; + +private: + void serialize(bool bSave); + void load_user_defs(); + +protected: + virtual bool on_sheet_event(TOperable_field& o, TField_event e, long jolly); + virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); + virtual void next_page(int p); + + +public: + void update_sheet(); + TGenera_ordini_mask(); + ~TGenera_ordini_mask(); +}; + +void TGenera_ordini_mask::update_sheet() +{ + TSheet_field & sf = sfield(F_ARTICLES); + TEsercizi_contabili esc; + TString query(_anamag_query); + TString16 grmerc(get(F_GRMERC)); + const int pos = query.find("KEY "); + TArticolo_giacenza art; + TString8 codmag(get(F_MAG)); + const TDate data(TODAY); + const int anno = data.year(); + + codmag.left_just(3); + codmag << get(F_DEP); + codmag.trim(); + + grmerc.left_just(3); + grmerc << get(F_SGRMERC); + grmerc.trim(); + + if (grmerc.full()) + { + if (pos > 0) + query[pos + 4] = '3'; + query << "\nFROM GRMERC=#GRMERC\nTO GRMERC=#GRMERC"; + } + else + if (pos > 0) + query[pos + 4] = '1'; + + TString select; + + const TString & codart = get(F_SCODART); + + if (codart.full()) + select << "(UPPER(" << ANAMAG_CODART << ")?=UPPER(\"" << codart << "\"))"; + + const TString & desart = get(F_SDESART); + + if (desart.full()) + { + if (select.full()) + select << "&&"; + select << "(UPPER(" << ANAMAG_DESCR << ")?=UPPER(\"" << desart << "\"))"; + } + + const TString & desagg = get(F_SDESAGG); + + if (desagg.full()) + { + if (select.full()) + select << "&&"; + select << "(UPPER(" << ANAMAG_DESCRAGG << ")?=UPPER(\"" << desagg << "\"))"; + } + + + const TString & codforn = get(F_SCODFOR); + + if (codforn.full()) + { + if (select.full()) + select << "&&"; + select << "(" << ANAMAG_CODFORN << "==\"" << codforn << "\")"; + } + + const TString & ragsoc = get(F_SRAGSOC); + + if (ragsoc.full()) + { + if (select.full()) + select << "&&"; + select << "(UPPER(CLIFO.RAGSOC)?=UPPER(\"" << ragsoc << "\"))"; + } + + if (select.full()) + { + int pos = query.find("SELECT "); + if (pos > 0) + { + const int acapo = query.find('\n', pos); + query.insert("((", pos+7); + select.insert(")&&("); + select << "))"; + query.insert(select, acapo+2); + } + else + { + pos = query.find('\n'); + select.insert("\nSELECT "); + query.insert(select, pos); + } + } + + + TArticoli_recordset recset(query, get_bool(F_SOTTOSCORTA), esc.date2esc(TDate(TODAY))); + TVariant var ; + + var = grmerc; + recset.set_var("#GRMERC", var); + var = user(); + recset.set_var("#USER", var); + + int i = 0; + + sf.destroy(); + + for (bool ok = recset.move_first(); ok; ok = recset.move_next()) + { + TToken_string & row = sf.row(i); + const TString & codart = recset.get(ANAMAG_CODART).as_string(); + + row.add(codart, sf.cid2index(F_CODART)); + art.read(codart); + const real giac = art.giacenza_anno(codmag, "", anno); + row.add(recset.get(ANAMAG_DESCR).as_string(), sf.cid2index(F_DESCR)); + row.add(recset.get("UMART.UM").as_string(), sf.cid2index(F_UM)); + + const long codforn = recset.get(ANAMAG_CODFORN).as_int(); + + row.add(codforn, sf.cid2index(F_FORNITORE)); + row.add(recset.get("CLIFO.RAGSOC").as_string(), sf.cid2index(F_RAGSOC)); + row.add(recset.get(ANAMAG_GIORNIRIOR).as_string(), sf.cid2index(F_LEADTIME)); + row.add(recset.get(ANAMAG_LOTTORIOR).as_string(), sf.cid2index(F_LOTTOMIN)); + row.add(recset.get(ANAMAG_DESCRAGG).as_string(), sf.cid2index(F_DESCRAGG)); + row.add(giac.stringa(), sf.cid2index(F_GIACENZA)); + + row.add(recset.get(ANAMAG_PPCONF).as_string(), sf.cid2index(F_PPCONF)); + row.add(recset.get(ANAMAG_USER1).as_string(), sf.cid2index(F_USER1)); + row.add(recset.get(ANAMAG_USER2).as_string(), sf.cid2index(F_USER2)); + row.add(recset.get(ANAMAG_USER3).as_string(), sf.cid2index(F_USER3)); + row.add(recset.get(ANAMAG_USER4).as_string(), sf.cid2index(F_USER4)); + row.add(recset.get(ANAMAG_USER5).as_string(), sf.cid2index(F_USER5)); + row.add(recset.get(ANAMAG_USER6).as_string(), sf.cid2index(F_USER6)); + row.add(recset.get(ANAMAG_USER7).as_string(), sf.cid2index(F_USER7)); + row.add(recset.get(ANAMAG_USER8).as_string(), sf.cid2index(F_USER8)); + row.add(recset.get(ANAMAG_USER9).as_string(), sf.cid2index(F_USER9)); + row.add(recset.get(ANAMAG_USER10).as_string(), sf.cid2index(F_USER10)); + sf.check_row(i++); + } +} + +void TGenera_ordini_mask::next_page(int p) +{ + TAutomask::next_page(p); + if (_filter_changed) + { + TSheet_field & sf = sfield(F_ARTICLES); + + if (win() == sf.parent()) + { + update_sheet(); + sf.force_update(); + _filter_changed = false; + } + } + +} + +bool TGenera_ordini_mask::on_sheet_event(TOperable_field& o, TField_event e, long jolly) +{ + TSheet_field& sht = (TSheet_field&)o; + + switch(e) + { + case se_query_del: + case se_query_add: + return false; + break; + default: + break; + } + return true; +} + +bool TGenera_ordini_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) +{ + bool ok = true; + switch (o.dlg()) + { + case F_GRMERC: + case F_SGRMERC: + case F_SOTTOSCORTA: + case F_SCODART: + case F_SDESART: + case F_SDESAGG: + case F_SCODFOR: + case F_SRAGSOC: + if (e == fe_modify) + _filter_changed = true; + break; + default: + break; + } + return ok; +} + +void TGenera_ordini_mask::serialize(bool bSave) +{ + const char* defpar = "or"; + TConfig ini(CONFIG_DITTA, defpar); + for (int i = fields()-1; i >= 0; i--) + { + TMask_field& f = fld(i); + const TFieldref* fr = f.field(); + if (fr != NULL) + { + if (bSave) + fr->write(ini, defpar, f.get()); + else + f.set(fr->read(ini, defpar)); + } + } +} + +void TGenera_ordini_mask::load_user_defs() +{ + const char* defpar = "or"; + TConfig ini(CONFIG_USER, defpar); + for (int i = fields()-1; i >= 0; i--) + { + TMask_field& f = fld(i); + const TFieldref* fr = f.field(); + if (fr != NULL) + { + const char * val = fr->read(ini, defpar); + if (*val) + { + f.set(val); + f.disable(); + } + } + } +} + +TGenera_ordini_mask::TGenera_ordini_mask() + : TAutomask("or1400a"), _filter_changed(false) + +{ + serialize(false); + load_user_defs(); + TConfig c(CONFIG_DITTA); + + _anamag_query = c.get("OR14_QUERY"); + + if (_anamag_query.blank()) + _anamag_query = "USE ANAMAG KEY 1\nJOIN UMART INTO CODART==CODART NRIGA==1\nJOIN CLIFO INTO TIPOCF==\"F\" CODCF==CODFORN"; + else + _anamag_query = esc(_anamag_query ); + + TSheet_field & sh = sfield(F_ARTICLES); + TMask & sh_mask = sh.sheet_mask(); + TString prompt; + + for (int i = 1; i <= 10; i++) + { + const int col = sh.cid2index(F_USER1 + i -1); + TEditable_field & f = sh_mask.efield(F_USER1 + i - 1); + + if (c.get_bool("CHK_USER", "ve", i) && c.get_bool("USERDEF", "or", i)) + { + prompt = c.get("PROMPT_USER", "ve", i); + prompt.rpad(20); + f.set_prompt(prompt); + sh.set_column_header(col, prompt); + } + else + { + f.hide(); + sh.delete_column(col); + } + } +} + +TGenera_ordini_mask::~TGenera_ordini_mask() +{ + serialize(true); +} + +class TCreazione_ordini : public TSkeleton_application +{ + TString_array _userfld; + + void generate_orders(TGenera_ordini_mask & mask); + +protected: + virtual bool create(); + virtual bool destroy(); + virtual void main_loop(); + +public: + TCreazione_ordini() {}; + virtual ~TCreazione_ordini() {}; +}; + +bool TCreazione_ordini::create() +{ + open_files(LF_DOC, LF_RIGHEDOC, LF_CONDV, LF_RCONDV, LF_ANAMAG, LF_SCONTI, LF_UMART, LF_DESLIN, LF_CODCORR, + LF_TAB, LF_TABCOM, LF_CLIFO, LF_CFVEN, LF_INDSP, LF_OCCAS, LF_PCON, LF_MOV, LF_STOMAG, + LF_MOVMAG, LF_RMOVMAG, LF_MAG, LF_SVRIEP, LF_AGENTI, LF_PERCPROV, LF_ATTIV, LF_CAUSALI, 0); + TConfig c(CONFIG_DITTA); + + for (int i = 0; i < 10; i++ ) + _userfld.add(c.get("USERFLD", NULL, i + 1), i); + + return TSkeleton_application::create(); +} + +void TCreazione_ordini::generate_orders(TGenera_ordini_mask & mask) +{ + TSheet_field & sf = mask.sfield(F_ARTICLES); + TAssoc_array orders; + const TDate datadoc(TODAY); + const TString16 codnum(mask.get(F_CODNUM)); + const TString16 tipodoc(mask.get(F_TIPODOC)); + const TString8 tipo_prezzo(mask.get(F_PREZZO)); + long minforn = 999999L; + long maxforn = 0L; + const TString commessat = mask.get(F_CDCT); + const TString faset = mask.get(F_FSCT); + TString16 codmag(mask.get(F_MAG)); + + codmag.right_just(3); + codmag << mask.get(F_DEP); + + FOR_EACH_SHEET_ROW(sf, n, row) + { + const real qta(row->get(sf.cid2index(F_QTA))); + if (qta > ZERO) + { + const TString16 codforn(row->get(sf.cid2index(F_FORNITORE))); + const long cod = atoi(codforn); + const TDate datacons(row->get(sf.cid2index(F_DATACONS))); + TString16 key ; key. format ("F|%s", (const char *) codforn); + const TRectype & forn = cache().get(LF_CLIFO, key); + const TRectype & forven = cache().get(LF_CFVEN, key); + const TString16 codval(forn.get(CLI_CODVAL)); + TString16 codiva(forven.get(CFV_ASSFIS)); + const TString commessa = row->get(sf.cid2index(F_CDC)); + const TString fase = row->get(sf.cid2index(F_FSC)); + TDocumento * d = (TDocumento *)orders.objptr(codforn); + + if (d == NULL) + { + TTipo_documento tipo(tipodoc); + + d = new TDocumento('D', datadoc.year(), codnum, 0L); + d->put(DOC_TIPODOC, tipodoc); + d->put(DOC_TIPOCF, "F"); + d->put(DOC_CODCF, codforn); + d->put(DOC_DATADOC, datadoc); + d->put(DOC_DATACONS, datacons); + d->put(DOC_CODVAL, codval); + d->put(DOC_CODLIN, forn.get(CLI_CODLIN)); + d->put(DOC_CODPAG, forn.get(CLI_CODPAG)); + d->put(DOC_CODABIA, forn.get(CLI_CODABI)); + d->put(DOC_CODCABA, forn.get(CLI_CODCAB)); + d->put(DOC_IBAN, forn.get(CLI_IBAN)); + d->put(DOC_CODABIP, forven.get(CFV_CODABIPR)); + d->put(DOC_CODCABP, forven.get(CFV_CODCABPR)); + d->put(DOC_RAGGR, forven.get(CFV_RAGGDOC)); + d->put(DOC_RAGGREFF, forven.get(CFV_RAGGEFF)); + d->put(DOC_CODINDSP, forven.get(CFV_CODINDSP)); + d->put(DOC_CODAG, forven.get(CFV_CODAG)); + d->put(DOC_ZONA, forven.get(CFV_CODZONA)); + d->put(DOC_CODSPMEZZO, forven.get(CFV_CODSPMEZZO)); + d->put(DOC_CODPORTO, forven.get(CFV_CODPORTO)); + d->put(DOC_CODNOTESP1, forven.get(CFV_CODNOTESP1)); + d->put(DOC_CODNOTESP2, forven.get(CFV_CODNOTESP2)); + d->put(DOC_CODNOTE, forven.get(CFV_CODNOTE)); + d->put(DOC_CODVETT1, forven.get(CFV_CODVETT1)); + d->put(DOC_CODVETT2, forven.get(CFV_CODVETT2)); + d->put(DOC_CODVETT3, forven.get(CFV_CODVETT3)); + d->put(DOC_PERCSPINC, forven.get(CFV_PERCSPINC)); + d->put(DOC_ADDBOLLI, forven.get(CFV_ADDBOLLI)); + d->put(DOC_CATVEN, forven.get(CFV_CATVEN)); + d->put(DOC_CODLIST, forven.get(CFV_CODLIST)); + d->put(DOC_CODCMS, commessat); + d->put(DOC_NOTE, mask.get(F_NOTE)); + const TString & causmag = tipo.caus_mov(); + d->put(DOC_CAUSMAG, causmag); + orders.add(codforn, d); + if (cod < minforn) + minforn = cod; + if (cod > maxforn) + maxforn = cod; + } + + TRiga_documento & rdoc = d->new_row("01"); + const TString codart(row->get(sf.cid2index(F_CODART))); + + rdoc.put(RDOC_CODMAG, codmag); + rdoc.put(RDOC_CODART, codart); + rdoc.put(RDOC_CODARTMAG, codart); + rdoc.put(RDOC_CHECKED, "X"); + rdoc.put(RDOC_DESCR, row->get(sf.cid2index(F_DESCR))); + + const TString descr_agg(row->get(sf.cid2index(F_DESCRAGG))); + + if (descr_agg.full()) + { + rdoc.put(RDOC_DESCLUNGA, "X"); + rdoc.put(RDOC_DESCEST, descr_agg); + } + rdoc.put(RDOC_UMQTA, row->get(sf.cid2index(F_UM))); + rdoc.put(RDOC_QTA, qta); + rdoc.put(RDOC_DATACONS, datacons); + const TRectype & articolo = cache().get(LF_ANAMAG, codart); + TPrice prezzo; + + if (tipo_prezzo == "U") + prezzo = articolo.get_real(ANAMAG_ULTCOS1); + else + prezzo = articolo.get_real(ANAMAG_COSTSTD); + prezzo.change_value(codval); + rdoc.put(RDOC_PREZZO, prezzo.get_num()); + if (codiva.full()) + rdoc.put(RDOC_CODIVA, codiva); + else + rdoc.put(RDOC_CODIVA, articolo.get(ANAMAG_CODIVA)); + rdoc.put(RDOC_CODCMS, commessa); + rdoc.put(RDOC_FASCMS, fase); + for (int i = 0; i < 10 ; i++) + if (_userfld.row(i).full()) + rdoc.put(_userfld.row(i), mask.get(F_USER1 + i)); + + rdoc.put(RDOC_CODAGG1, row->get(sf.cid2index(F_CODAGG1))); + rdoc.put(RDOC_CODAGG2, row->get(sf.cid2index(F_CODAGG2))); + } + } + int cnt = 0; + for (long cod = minforn; cod <= maxforn; cod++) + { + TString16 key; key.format("%ld", cod); + TDocumento * d = (TDocumento *) orders.objptr(key); + + if ( d != NULL) + { + d->write(); + cnt++; + } + } + message_box("Attenzione sono stati generati %d documenti", cnt); +} + +void TCreazione_ordini::main_loop() +{ + TGenera_ordini_mask mask; + + while (true) + { + mask.update_sheet(); + if (mask.run() == K_ENTER) + generate_orders(mask); + else break; + } +} + +bool TCreazione_ordini::destroy() +{ + return TSkeleton_application::destroy(); +} + +int or1400(int argc, char** argv) +{ + TCreazione_ordini a; + a.run(argc,argv,TR("Generazione Ordini a fornitore")); + return 0; +} + diff --git a/or/or1400a.h b/or/or1400a.h new file mode 100755 index 000000000..5821ede72 --- /dev/null +++ b/or/or1400a.h @@ -0,0 +1,53 @@ +// Defines per maschera + +#define F_GRMERC 151 +#define F_DGRMERC 152 +#define F_SGRMERC 153 +#define F_DSGRMERC 154 +#define F_SOTTOSCORTA 155 +#define F_ARTICLES 156 +#define F_CODNUM 157 +#define F_DESNUM 158 +#define F_TIPODOC 159 +#define F_DESTIPODOC 160 +#define F_MAG 161 +#define F_DESMAG 162 +#define F_DEP 163 +#define F_DESDEP 164 +#define F_PREZZO 165 +#define F_CDCT 166 +#define F_FSCT 167 +#define F_NOTE 168 +#define F_SCODART 169 +#define F_SDESART 170 +#define F_SDESAGG 171 +#define F_SCODFOR 172 +#define F_SRAGSOC 173 + + +#define F_CODART 101 +#define F_DESCR 102 +#define F_UM 103 +#define F_QTA 104 +#define F_DATACONS 105 +#define F_FORNITORE 106 +#define F_RAGSOC 107 +#define F_CDC 108 +#define F_FSC 109 +#define F_CODAGG1 110 +#define F_CODAGG2 111 +#define F_LEADTIME 112 +#define F_LOTTOMIN 113 +#define F_DESCRAGG 114 +#define F_GIACENZA 115 +#define F_PPCONF 116 +#define F_USER1 117 +#define F_USER2 118 +#define F_USER3 119 +#define F_USER4 120 +#define F_USER5 121 +#define F_USER6 122 +#define F_USER7 123 +#define F_USER8 124 +#define F_USER9 125 +#define F_USER10 126 diff --git a/or/or1400a.uml b/or/or1400a.uml new file mode 100755 index 000000000..cefb2be24 --- /dev/null +++ b/or/or1400a.uml @@ -0,0 +1,514 @@ +#include "or1400a.h" + +TOOLBAR "" 0 -3 0 3 + +BUTTON DLG_OK 11 2 +BEGIN + PROMPT -12 -11 "" +END + +BUTTON DLG_QUIT 11 2 +BEGIN + PROMPT -22 -11 "" +END + +ENDPAGE + +PAGE "Generazione Ordini fornitori" -1 -1 80 20 + +SPREADSHEET F_ARTICLES 0 -2 +BEGIN + PROMPT 1 2 "Articoli" + ITEM "Codice@20" + ITEM "Descrizione@50" + ITEM "UM" + ITEM "Quantitą@15" + ITEM "Data Consegna" + ITEM "Codice Fornitore" + ITEM "Ragione sociale@50" + ITEM "Commessa@20" + ITEM "Fase@10" + ITEM "Codice Aggiuntivo 1@20" + ITEM "Codice Aggiuntivo 2@20" + ITEM "Lead\ntime@5" + ITEM "Lotto minimo\ndi riordino@10" + ITEM "Descrizione aggiuntiva@50" + ITEM "Giacenza@15" + ITEM "Pezzi per conf.@15" + ITEM "Campo Aggiuntivo 1@15" + ITEM "Campo Aggiuntivo 2@15" + ITEM "Campo Aggiuntivo 3@15" + ITEM "Campo Aggiuntivo 4@15" + ITEM "Campo Aggiuntivo 5@15" + ITEM "Campo Aggiuntivo 6@15" + ITEM "Campo Aggiuntivo 7@15" + ITEM "Campo Aggiuntivo 8@15" + ITEM "Campo Aggiuntivo 9@15" + ITEM "Campo Aggiuntivo 10@15" +END + +ENDPAGE + +PAGE "Note" -1 -1 80 20 + +MEMO F_NOTE 70 16 +BEGIN + PROMPT 2 2 "Note " + FLAG "U" +END + +ENDPAGE + +PAGE "Filtri" -1 -1 80 20 + +STRING F_GRMERC 3 +BEGIN + PROMPT 2 2 "Gruppo merceologico " + FLAG "U" + USE GMC KEY 1 SELECT CODTAB[4,5]=="" + INPUT CODTAB F_GRMERC + DISPLAY "Codice" CODTAB[1,3] + DISPLAY "Descrizione@50" S0 + OUTPUT F_GRMERC CODTAB[1,3] + OUTPUT F_DGRMERC S0 + CHECKTYPE SEARCH + FIELD OR14_GRM +END + +STRING F_DGRMERC 50 35 +BEGIN + PROMPT 35 2 "" + USE GMC KEY 2 SELECT CODTAB[4,5]=="" + INPUT S0 F_DGRMERC + DISPLAY "Codice" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT F_GRMERC CODTAB[1,3] + OUTPUT F_DGRMERC S0 + CHECKTYPE SEARCH +END + +STRING F_SGRMERC 2 +BEGIN + PROMPT 2 3 "Sottogruppo merceologico " + FLAG "U" + USE GMC + INPUT CODTAB[1,3] F_GRMERC + INPUT CODTAB[4,5] F_SGRMERC + DISPLAY "Codice" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT F_GRMERC CODTAB[1,3] + OUTPUT F_SGRMERC CODTAB[4,5] + OUTPUT F_DSGRMERC S0 + CHECKTYPE NORMAL + FIELD OR14_SGR +END + +STRING F_DSGRMERC 50 35 +BEGIN + PROMPT 35 3 "" + USE GMC KEY 2 SELECT CODTAB[4,5] != "" + INPUT S0 F_DSGRMERC + DISPLAY "Descrizione@50" S0 + DISPLAY "Codice" CODTAB + COPY OUTPUT F_SGRMERC + CHECKTYPE NORMAL +END + +BOOLEAN F_SOTTOSCORTA +BEGIN + PROMPT 2 4 "Sottoscorta" + FIELD OR14_SSC +END + +STRING F_CDCT 20 +BEGIN + PROMPT 2 6 "CDC/Commessa " + FLAGS "UZ" + USE CMS + INPUT CODTAB F_CDCT + DISPLAY "Codice@20" CODTAB + DISPLAY "Descrizione@70" S0 + OUTPUT F_CDCT CODTAB + FILED OR14_CDCT + CHECKTYPE NORMAL +END + +STRING F_FSCT 10 +BEGIN + PROMPT 50 6 "Fase " + FLAGS "UZ" + USE FSC + INPUT CODTAB F_FSCT + DISPLAY "Codice@20" CODTAB + DISPLAY "Descrizione@70" S0 + OUTPUT F_FSCT CODTAB + FIELD OR14_FSCT + CHECKTYPE NORMAL +END + +STRING F_SCODART 20 +BEGIN + PROMPT 2 8 "Codice articolo " +END + +STRING F_SDESART 50 +BEGIN + PROMPT 2 10 "Descrizione " +END + +STRING F_SDESAGG 50 +BEGIN + PROMPT 2 12 "Descrizione aggiuntiva " +END + +STRING F_SCODFOR 7 +BEGIN + PROMPT 2 14 "Codice fornitore " + USE LF_CLIFO + INPUT TIPOCF "F" + INPUT CODCF F_SCODFOR + DISPLAY "Codice " CODCF + DISPLAY "Ragione sociale@50" RAGSOC + OUTPUT F_SCODFOR CODCF +END + +STRING F_SRAGSOC 50 +BEGIN + PROMPT 2 16 "Ragione sociale " +END + +ENDPAGE + +PAGE "Parametri" -1 -1 80 20 + +STRING F_CODNUM 4 +BEGIN + PROMPT 2 2 "Numerazione " + USE %NUM + INPUT CODTAB F_CODNUM + DISPLAY "Codice" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT F_CODNUM CODTAB + OUTPUT F_DESNUM S0 + FLAG "UG" + CHECKTYPE REQUIRED + FIELD OR14_NUM +END + +STRING F_DESNUM 50 +BEGIN + PROMPT 24 2 "" + USE %NUM KEY 2 + INPUT S0 F_DESNUM + DISPLAY "Descrizione@50" S0 + DISPLAY "Codice" CODTAB + COPY OUTPUT F_CODNUM + CHECKTYPE SEARCH +END + +STRING F_TIPODOC 4 +BEGIN + PROMPT 2 4 "Tipo " + USE %TIP + INPUT CODTAB F_TIPODOC + DISPLAY "Codice" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT F_TIPODOC CODTAB + OUTPUT F_DESTIPODOC S0 + CHECKTYPE REQUIRED + FLAG "UG" + FIELD OR14_TIP +END + +STRING F_DESTIPODOC 50 +BEGIN + PROMPT 24 4 "" + USE %TIP KEY 2 + INPUT S0 F_DESTIPODOC + DISPLAY "Descrizione@50" S0 + DISPLAY "Codice" CODTAB + COPY OUTPUT F_TIPODOC + CHECKTYPE SEARCH +END + +STRING F_MAG 3 +BEGIN + PROMPT 2 6 "Magazzino " + FLAGS "UG" + USE MAG SELECT CODTAB[4,5]=="" + INPUT CODTAB F_MAG + DISPLAY "Codice " CODTAB[1,3] + DISPLAY "Denominazione mag.@50 " S0 + OUTPUT F_MAG CODTAB[1,3] + CHECKTYPE NORMAL + FIELD OR14_MAG +END + +STRING F_DESMAG 50 +BEGIN + PROMPT 24 6 "" + USE MAG KEY 2 SELECT CODTAB[4,5]=="" + INPUT S0 F_DESMAG + DISPLAY "Denominazione magazzino@50" S0 + DISPLAY "Cod. magazzino" CODTAB[1,3] + DISPLAY "Cod. deposito" CODTAB[4,5] + OUTPUT F_MAG CODTAB[1,3] + CHECKTYPE SEARCH +END + +STRING F_DEP 2 +BEGIN + PROMPT 2 8 "Deposito " + FLAGS "U" + USE MAG SELECT (CODTAB[1,3]==#F_MAG)&&(CODTAB[4,5]!="") + INPUT CODTAB[1,3] F_MAG + INPUT CODTAB[4,5] F_DEP + DISPLAY "Codice " CODTAB + DISPLAY "Denominazione dep.@50 " S0 + OUTPUT F_MAG CODTAB[1,3] + OUTPUT F_DEP CODTAB[4,5] + CHECKTYPE SEARCH + FIELD OR14_DEP +END + +STRING F_DESDEP 50 +BEGIN + PROMPT 24 8 "" + USE MAG KEY 2 SELECT (CODTAB[1,3]==#F_MAG)&&(CODTAB[4,5]!="") + INPUT S0 F_DESDEP + COPY DISPLAY F_DESMAG + OUTPUT F_DEP CODTAB[4,5] + CHECKTYPE SEARCH +END + +LIST F_PREZZO 15 +BEGIN + PROMPT 2 10 "Prezzo " + ITEM "U|Ultimo Costo" + ITEM "S|Costo Standard" + FIELD OR14_TPR +END + +ENDPAGE +ENDMASK + +PAGE "Righe ordine" -1 -1 80 20 + +STRING F_CODART 20 +BEGIN + PROMPT 1 2 "Codice " + FLAGS "D" +END + +STRING F_DESCR 50 35 +BEGIN + PROMPT 42 2 "" + FLAGS "D" +END + +STRING F_UM 2 +BEGIN + PROMPT 2 4 "Unitą di misura " + FLAGS "UG" + USE LF_UMART KEY 2 SELECT CODART==#F_CODART + JOIN %UMS INTO CODTAB==UM + INPUT CODART F_CODART SELECT + INPUT UM F_UM + DISPLAY "U.M.@10" UM + DISPLAY "Descrizione@50" %UMS->S0 + DISPLAY "F.C.@10" FC + OUTPUT F_UM UM + CHECKTYPE REQUIRED +END + +NUMBER F_QTA 13 5 +BEGIN + PROMPT 25 4 "Quantitą " +END + +DATA F_DATACONS +BEGIN + PROMPT 48 4 "Data di consegna " + WARNING "Indicare la data di consegna" + VALIDATE REQIF_FUNC 1 F_QTA +END + +NUMBER F_FORNITORE 6 +BEGIN + PROMPT 2 6 "Codice fornitore " + FIELD CODCF + USE LF_CLIFO + INPUT TIPOCF "F" + INPUT CODCF F_FORNITORE + DISPLAY "Codice " CODCF + DISPLAY "Ragione sociale@50" RAGSOC + OUTPUT F_FORNITORE CODCF + OUTPUT F_RAGSOC RAGSOC + CHECKTYPE NORMAL + ADD RUN CG0 -1 +END + +STRING F_RAGSOC 50 35 +BEGIN + PROMPT 42 6 "" + USE LF_CLIFO KEY 2 + INPUT TIPOCF "F" + INPUT RAGSOC F_RAGSOC + DISPLAY "Ragione sociale@50" RAGSOC + DISPLAY "Codice " CODCF + COPY OUTPUT F_FORNITORE + CHECKTYPE SEARCH + ADD RUN CG0 -1 +END + +STRING F_CDC 20 +BEGIN + PROMPT 2 8 "CDC/Commessa " + FLAGS "UZ" + USE CMS + INPUT CODTAB F_CDC + DISPLAY "Codice@20" CODTAB + DISPLAY "Descrizione@70" S0 + OUTPUT F_CDC CODTAB + CHECKTYPE NORMAL +END + +STRING F_FSC 10 +BEGIN + PROMPT 42 8 "Fase " + FLAGS "UZ" + USE FSC + INPUT CODTAB F_FSC + DISPLAY "Codice@20" CODTAB + DISPLAY "Descrizione@70" S0 + OUTPUT F_FSC CODTAB + CHECKTYPE NORMAL +END + +STRING F_CODAGG1 20 +BEGIN + PROMPT 2 9 "Codice agg. 1 " +END + +STRING F_CODAGG2 20 +BEGIN + PROMPT 42 9 "Codice agg. 2 " +END + +NUMBER F_LEADTIME 5 +BEGIN + PROMPT 2 11 "Lead time " + FLAGS "D" +END + +NUMBER F_LOTTOMIN 10 3 +BEGIN + PROMPT 42 11 "Lotto " + FLAGS "D" +END + +MEMO F_DESCRAGG 50 4 +BEGIN + PROMPT 2 12 "Descr.aggiuntiva" + FLAGS "D" +END + +NUMBER F_GIACENZA 15 5 +BEGIN + PROMPT 2 18 "Giacenza" + FLAGS "D" +END + +NUMBER F_PPCONF 15 +BEGIN + PROMPT 2 19 "Pezzi per conf. " + FLAGS "D" +END + +BUTTON DLG_OK 11 2 +BEGIN + PROMPT -12 -1 "" +END + +BUTTON DLG_CANCEL 11 2 +BEGIN + PROMPT -22 -1 "" +END + +ENDPAGE + +PAGE "Campi Utente" -1 -1 80 20 + +STRING F_USER1 20 +BEGIN + PROMPT 2 2 "Campo utente 1 " + FLAGS "D" +END + +STRING F_USER2 20 +BEGIN + PROMPT 2 4 "Campo utente 2 " + FLAGS "D" +END + +STRING F_USER3 20 +BEGIN + PROMPT 2 6 "Campo utente 3 " + FLAGS "D" +END + +STRING F_USER4 20 +BEGIN + PROMPT 2 8 "Campo utente 4 " + FLAGS "D" +END + +STRING F_USER5 20 +BEGIN + PROMPT 2 10 "Campo utente 5 " + FLAGS "D" +END + +STRING F_USER6 20 +BEGIN + PROMPT 2 12 "Campo utente 6 " + FLAGS "D" +END + +STRING F_USER7 20 +BEGIN + PROMPT 2 14 "Campo utente 7 " + FLAGS "D" +END + +STRING F_USER8 20 +BEGIN + PROMPT 2 16 "Campo utente 8 " + FLAGS "D" +END + +STRING F_USER9 20 +BEGIN + PROMPT 2 18 "Campo utente 9 " + FLAGS "D" +END + +STRING F_USER10 20 +BEGIN + PROMPT 2 20 "Campo utente 10 " + FLAGS "D" +END + +BUTTON DLG_OK 11 2 +BEGIN + PROMPT -12 -1 "" +END + +BUTTON DLG_CANCEL 11 2 +BEGIN + PROMPT -22 -1 "" +END + +ENDPAGE + +ENDMASK \ No newline at end of file diff --git a/or/ormenu.men b/or/ormenu.men index 5f5df2a87..cca7d1e1b 100755 --- a/or/ormenu.men +++ b/or/ormenu.men @@ -5,4 +5,5 @@ Module = 33 Flags = "" Item_01 = "Stampa ordini", "or1.exe -0","F" Item_02 = "Stampa disponibilita' articoli", "or1.exe -1","F" -Item_03 = "Scarico e ripristino documenti", "ve5.exe -0","F" +Item_03 = "Generazione ordini a fornitore", "or1.exe -3","F" +Item_04 = "Scarico e ripristino documenti", "ve5.exe -0","F" diff --git a/ps/indice_programmi.txt b/ps/indice_programmi.txt index bf1f400ef..ea2b3f2cf 100755 --- a/ps/indice_programmi.txt +++ b/ps/indice_programmi.txt @@ -28,9 +28,12 @@ Trasferimento Maestri a TeamSystem Convesione file Landi PG0069 -Importazione e contabilizzazione fatture Nautilus +Importazione e contabilizzazione fatture Nautilus e Bonomo +PS0430 Il Cigno +Correlazioni articoli utenti + PS0017 Gestione Incassi diff --git a/ps/pf0001100.cpp b/ps/pf0001100.cpp index 71b10b9a4..5dd0ec0b3 100755 --- a/ps/pf0001100.cpp +++ b/ps/pf0001100.cpp @@ -566,6 +566,7 @@ void TStampa_etich_art::main_loop() _ncopie = mask.get_int(F_QTA); rep.set_filter(mask); b.add(rep); + b.print_labels(1, 2, _ncopie); } else { @@ -574,8 +575,9 @@ void TStampa_etich_art::main_loop() rep.load("pf0001100b"); rep.set_filter(mask); b.add(rep); + b.print_labels(1, 2, _ncopie); } - b.print_labels(1, 2, _ncopie); + } } diff --git a/ps/pf0001100.uml b/ps/pf0001100.uml index a3f852b5f..4e2af0b47 100755 --- a/ps/pf0001100.uml +++ b/ps/pf0001100.uml @@ -117,7 +117,7 @@ END STRING F_LIST 3 BEGIN PROMPT 2 16 "Codice Listino " - FIELD LIST + FIELD #LIST FLAG "U" USE LF_CONDV INPUT TIPO "L" diff --git a/ps/pg0069.cpp b/ps/pg0069.cpp index 4ca4b7834..aab1762ab 100755 --- a/ps/pg0069.cpp +++ b/ps/pg0069.cpp @@ -9,7 +9,7 @@ int main(int argc, char** argv) { case 0: default: - pg0069100(argc, argv); break; //importazione e contabilizzazione fatture Nautilus + pg0069100(argc, argv); break; //importazione e contabilizzazione fatture Nautilus e Bonomo } exit(0); return 0; diff --git a/ps/pg0069100.cpp b/ps/pg0069100.cpp index 0212a87df..046eea58d 100755 --- a/ps/pg0069100.cpp +++ b/ps/pg0069100.cpp @@ -715,6 +715,6 @@ void TNautilus::main_loop() int pg0069100 (int argc, char* argv[]) { TNautilus main_app; - main_app.run(argc, argv, TR("Importazione Nautilus")); + main_app.run(argc, argv, TR("Importazione Documenti")); return true; } diff --git a/ps/ps0920100.cpp b/ps/ps0920100.cpp index efc335808..7754097cf 100755 --- a/ps/ps0920100.cpp +++ b/ps/ps0920100.cpp @@ -19,11 +19,19 @@ protected: void update_sheet(); public: - TCursor_sheet & sheet() const { return *_sht;} + TCursor_sheet& sheet() const; TMaskPs09201(); virtual ~TMaskPs09201(); }; +TCursor_sheet& TMaskPs09201::sheet() const +{ + if (_sht == NULL) // Non si sa mai! + ((TMaskPs09201*)this)->update_sheet(); + return *_sht; +} + + TMaskPs09201::TMaskPs09201() : TAutomask("ps0920100a"), _sht(NULL) { @@ -95,8 +103,7 @@ void TMaskPs09201::update_sheet() class TStampaProduzionePs0920 : public TSkeleton_application { - TMaskPs09201 * _mask; - virtual bool check_autorization() const {return false;} + virtual bool check_autorization() const { return false; } virtual const char * extra_modules() const {return "ve";} @@ -105,64 +112,60 @@ protected: virtual bool create(); public: - const TMaskPs09201 & mask() const {return *_mask;} virtual ~TStampaProduzionePs0920(); }; void TStampaProduzionePs0920::main_loop() { - while (_mask->run() == K_ENTER) + TMaskPs09201 m; + + while (m.run() == K_ENTER) { - TReport_book book; - TCursor_sheet & s = _mask->sheet(); - TCursor * cur = s.cursor(); - const long items = cur->items(); - - for (long pos= 0L; pos curr(); - TReport rep; - TFilename report_name("OrdineProd.rep"); - - report_name.custom_path(); - if (rep.load(report_name)) + if (s.checked(pos)) { - TRecordset * r = rep.recordset(); + cur = pos; + const TRectype & rec = cur.curr(); + TRecordset & r = *rep.recordset(); + TVariant var; - if (r != NULL) - { - TVariant var; - - var = _mask->get(F_NUM); - r->set_var("#S_NUM", var); - var = rec.get(RDOC_ANNO); - r->set_var("#S_ANNO", var); - var = rec.get(RDOC_NDOC); - r->set_var("#S_NDOC", var); - var = rec.get(RDOC_NRIGA); - r->set_var("#S_NRIGA", var); - } + var = rec.get(RDOC_CODNUM); + r.set_var("#S_NUM", var); + var = rec.get(RDOC_ANNO); + r.set_var("#S_ANNO", var); + var = rec.get(RDOC_NDOC); + r.set_var("#S_NDOC", var); + var = rec.get(RDOC_NRIGA); + r.set_var("#S_NRIGA", var); + var = rec.get(RDOC_IDRIGA); + r.set_var("#S_IDRIGA", var); + book.add(rep); } - book.add(rep); } + book.print_or_preview(); } - if (book.pages() > 0) - book.print_or_preview(); } } bool TStampaProduzionePs0920::create() { - _mask = new TMaskPs09201; return TSkeleton_application:: create(); } TStampaProduzionePs0920::~TStampaProduzionePs0920() { - delete _mask; } TStampaProduzionePs0920 & app() { return (TStampaProduzionePs0920&) main_app();} diff --git a/ps/ps0920100a.uml b/ps/ps0920100a.uml index 554e70323..b9db51e01 100755 --- a/ps/ps0920100a.uml +++ b/ps/ps0920100a.uml @@ -1,6 +1,6 @@ #include "ps0920100a.h" -PAGE "Stampa ordini di produzione" -1 -1 80 8 +PAGE "Stampa ordini di produzione" -1 -1 80 9 GROUPBOX -1 78 5 BEGIN @@ -71,7 +71,7 @@ END STRING F_PROFILO 70 50 BEGIN - PROMPT 8 -3 "Profilo " + PROMPT 8 -4 "Profilo " PSELECT GROUP 1 END diff --git a/ps/pt0002.cpp b/ps/pt0002.cpp new file mode 100755 index 000000000..0a9dc7432 --- /dev/null +++ b/ps/pt0002.cpp @@ -0,0 +1,16 @@ +#include + +#include "pt0002.h" + +int main(int argc, char** argv) +{ + int n = argc > 1 ? atoi(argv[1]+1) : 0; + switch(n) + { + case 0: + default: + pt0002100(argc, argv); break; //importazione di clienti/fornitori da file CSV + } + exit(0); + return 0; +} \ No newline at end of file diff --git a/ps/pt0002.h b/ps/pt0002.h new file mode 100755 index 000000000..4635d312b --- /dev/null +++ b/ps/pt0002.h @@ -0,0 +1 @@ +int pt0002100(int argc, char* argv[]); diff --git a/ps/pt0002100.cpp b/ps/pt0002100.cpp new file mode 100755 index 000000000..d2cc993df --- /dev/null +++ b/ps/pt0002100.cpp @@ -0,0 +1,483 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pt0002.h" +#include "pt0002100a.h" + +#include "../cg/cglib01.h" + +#include "clifo.h" +#include "comuni.h" + +/////////////////////////////////////////////////////////// +// TClient_textset +/////////////////////////////////////////////////////////// + +class TClifo_recset : public TCSV_recordset +{ + TAssoc_array _index; + +protected: + virtual TRecnotype new_rec(const char* buf = NULL); + +public: + const TString& rag_sociale() const; + TClifo_recset(const char * query); +}; + + +TRecnotype TClifo_recset::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 == ',') + { + 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; +} + +//funzione che crea il campo ragione sociale dai primi 2 campi del file csv +const TString& TClifo_recset::rag_sociale() const +{ + const TString& nome = get(1).as_string(); + TString ragsoc = get(0).as_string(); + if (nome.full()) + { + ragsoc.cut(30); + ragsoc.left_just(30); + ragsoc << nome; + } + ragsoc.cut(50); + return get_tmp_string() = ragsoc; +} + +TClifo_recset::TClifo_recset(const char * fileName) + : TCSV_recordset("CSV(,)\n") +{ + load_file(fileName); +} + +/////////////////////////////////////////////////////////// +// TAutomask +/////////////////////////////////////////////////////////// + +class TImportaClifo_mask : public TAutomask +{ +protected: + virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); + +public: + TImportaClifo_mask(); +}; + +TImportaClifo_mask::TImportaClifo_mask() :TAutomask ("pt0002100a") +{ +} + +bool TImportaClifo_mask::on_field_event(TOperable_field& f, TField_event e, long jolly) +{ + switch (f.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) + { + f.set(as.row(as.selected())); + } + } + break; + default: + break; + } + return true; +} + +/////////////////////////////////////// +// TSkeleton_application +/////////////////////////////////////// +class TClifoCSV : public TSkeleton_application +{ + virtual bool check_autorization() const {return false;} + virtual const char * extra_modules() const {return "ve";} + + TImportaClifo_mask* _msk; + TConfig* _configfile; + + +protected: + long find_clifo(const char tipo, const TString& cofi, const TString& paiv, const TString& ragsoc) const; + bool safe_put(TLocalisamfile& clienti, const char* field, const char* val) const; + long find_last_clifo(const char tipo) const; + void pulisci_cap(TString& cap) const; + + +public: + virtual bool create(); + virtual bool destroy(); + virtual void main_loop(); + virtual void ini2mask(); + virtual void mask2ini(); + bool transfer(const TFilename& file); + + TClifoCSV() {}; +}; + +TClifoCSV& app() { return (TClifoCSV&) main_app(); } + +///////////////////////////////// +// ricerca clifo +///////////////////////////////// + +//funzione che ricerca un cliente o un fornitore nel file clifo di campo +//restituisce 0 (zero) se non lo trova, se no cerca il pił simile possibile +long TClifoCSV::find_clifo(const char tipo, const TString& cofi, const TString& paiv, const TString& ragsoc) const +{ + long found=0; + + TRelation clifo(LF_CLIFO); + TRectype& rec = clifo.curr(); + TString up_ragsoc = ragsoc; + up_ragsoc.upper(); + + for (int key = 2; key<=5 && !found; key++) + { + bool good_key = false; // Assumiamo che la chiave sia icompleta + + rec.zero(); + rec.put(CLI_TIPOCF,tipo); + switch (key) + { + case 2: rec.put(CLI_RAGSOC,ragsoc); good_key = ragsoc.full(); break; + case 4: rec.put(CLI_COFI,cofi); good_key = cofi.full(); break; + case 5: rec.put(CLI_PAIV,paiv); good_key = paiv.full(); break; + default: break; + } + + if (good_key) // Se la chiave e' completa ... cerco bene + { + TCursor cur(&clifo,"", key, &rec, &rec); + const TRecnotype items = cur.items(); + + if (items > 0) + { + double best = -1; + + TString80 cur_ragsoc; + + cur.freeze(); + for (cur=0; cur.pos() < items; ++cur) + { + cur_ragsoc = rec.get(CLI_RAGSOC); + cur_ragsoc.upper(); + + // funzione che mi dice quanto due stringhe si assomiglino + const double var = xvt_str_fuzzy_compare(up_ragsoc, cur_ragsoc); + if (var > best) + { + best = var; + found = rec.get_long(CLI_CODCF); + } + } + } + } + } + return found; +} + +///////////////////////////////// +// aggiornamento clifo +///////////////////////////////// + +//funzione che effettua la put solo se non cerco di inserire un campo vuoto +bool TClifoCSV::safe_put(TLocalisamfile& file, const char* field, const char* val) const +{ + const bool ok = val && *val; + if (ok) + file.put(field, val); + return ok; +} + +//funzione che trova il primo codice libero di un cliento o di un fornitore +long TClifoCSV::find_last_clifo(const char tipo) const +{ + TLocalisamfile clifo(LF_CLIFO); + long codcf = 1L ; + if (tipo == 'C') + { + clifo.put(CLI_TIPOCF, 'F'); + if (clifo.read(_isgteq) == NOERR) + clifo.prev(); + else + clifo.last(); + + if (clifo.get_char(CLI_TIPOCF) == 'C') + codcf += clifo.get_long(CLI_CODCF); + } + else + { + clifo.last(); + if (clifo.get_char(CLI_TIPOCF) == 'F') + codcf+=clifo.get_long(CLI_CODCF); + } + return codcf; +} + +void TClifoCSV::pulisci_cap(TString& cap) const +{ + TString8 str; + for (int i = 0; cap[i] && str.len() < 5; i++) + if (isdigit(cap[i])) + str << cap[i]; + cap = str; +} + +bool TClifoCSV::transfer(const TFilename& file) +{ + const char tipo = _msk->get(F_TIPO)[0]; + const char* head = tipo == 'C' ? TR("Trasferimento clienti") : TR("Trasferimento fornitori"); + + TLog_report log(head); + + TClifo_recset s(file); + + TLocalisamfile clifo(LF_CLIFO); + + TProgind pi(s.items(),head,true,true); + + for (bool ok=s.move_first();ok;ok=s.move_next()) + { + if (!pi.addstatus(1)) + break; + + const TString ragsoc = s.rag_sociale(); + if (ragsoc.full()) + { + const TString16 cofi = s.get(2).as_string(); //get da file del cod. fisc. + const TString16 paiv = s.get(3).as_string(); //get da file della p. iva + + const long var = find_clifo(tipo,cofi,paiv,ragsoc); //controllo se il clifo esiste gią + + clifo.zero(); + clifo.put(CLI_TIPOCF, tipo); + + if (var) + { + //se esiste leggo il record corrispondente + clifo.put(CLI_CODCF,var); + clifo.read(); + } + else + { + //se no ne creo uno nuovo + long codcf = find_last_clifo(tipo); + clifo.put(CLI_CODCF, codcf); + } + + safe_put(clifo, CLI_RAGSOC, ragsoc); //ragsoc + if (!var) + safe_put(clifo, CLI_TIPOAPER, s.get(1).is_empty() ? "G" : "F"); + + + safe_put(clifo, CLI_PAIV, paiv); //p.iva + safe_put(clifo, CLI_COFI, cofi); //cod. fisc. + + + safe_put(clifo, CLI_INDCF, s.get(4).as_string()); //indirizzo + safe_put(clifo, CLI_CIVCF, s.get(5).as_string()); //num. civico + + if (s.get(6).as_string().empty()) //italiano + { + TString cap = s.get(9).as_string(); + pulisci_cap(cap); + + TString80 comune = s.get(11).as_string(); //comune o localita' + comune.trim(); + safe_put(clifo, CLI_CAPCF, cap); //cap + const TString& codcom = cap2comune(cap, comune); + if (codcom.blank()) + { + if (s.get(10).as_string().full()) + comune << " (" << s.get(10).as_string() << ')'; //inserisce la localitą se non trova un comune + safe_put(clifo, CLI_LOCCF, comune); + } + else + safe_put(clifo, CLI_COMCF, codcom); + } + else + { + TString comune = s.get(7).as_string(); + comune << ", " << s.get(8).as_string() << '(' << s.get(6).as_string() <<')'; //inserisce la localitą estera + safe_put(clifo, CLI_LOCCF, comune); + if (!var) + safe_put(clifo, CLI_ALLEG, "5"); // Cliente/Fornitore Estero + } + + const char* tp = tipo == 'C' ? TR("Cliente") : TR("Fornitore"); + TString str; + str << "Il "<< tp << " codice (" << clifo.get(CLI_CODCF) <<") " << ragsoc << " "; + + if (var) + { + const int err = clifo.rewrite(); + if (err == NOERR) + { + str << "č stato aggiornato"; + log.log(0, str); + } + else + { + str << "NON č stato aggiornato. Errore " << err; + log.log(2, str); + } + } + else + { + const int err = clifo.write(); + if (err == NOERR) + { + str << "č stato inserito"; + log.log(0, str); + } + else + { + str << "NON č stato inserito. Errore " << err; + log.log(2, str); + } + } + + if (cofi.empty() && paiv.empty()) + { + TString str; + str << "Il " << tp << ' ' << ragsoc << " non ha nč CODICE FISCALE nč PARTITA IVA"; + log.log(1, str); + } + } + + } + + TReport_book buc; + buc.add(log); + buc.preview(); + + return true; +} + +void TClifoCSV::mask2ini() +{ + //carica i parametri del file di configurazione + _configfile->set_paragraph("MAIN"); + for (int i = 0; i < _msk->fields() ; i++) + { + TMask_field& f = _msk->fld(i); + const TFieldref* fr = f.field(); + if (fr != NULL) + _configfile->set(fr->name(), f.get()); + } +} + +void TClifoCSV::ini2mask() +{ + //carica i parametri del file di configurazione + _configfile->set_paragraph("MAIN"); + for (int i = 0; i < _msk->fields() ; i++) + { + TMask_field& f = _msk->fld(i); + const TFieldref* fr = f.field(); + if (fr != NULL) + f.set(_configfile->get(fr->name())); + } +} + +bool TClifoCSV::create() +{ + _configfile = new TConfig("pt0002conf.ini"); + _msk = new TImportaClifo_mask(); + + + return TSkeleton_application::create(); +} + +bool TClifoCSV::destroy() +{ + delete _msk; + delete _configfile; + return TApplication::destroy(); +} + +void TClifoCSV::main_loop() +{ + KEY tasto; + ini2mask(); + tasto = _msk->run(); + if (tasto == K_ENTER) + { + mask2ini(); + + //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("Importazione documenti completata")); + } + } +} + +int pt0002100 (int argc, char* argv[]) +{ + TClifoCSV main_app; + main_app.run(argc, argv, TR("Importazione Clienti/Fornitori")); + return true; +} diff --git a/ps/pt0002100a.h b/ps/pt0002100a.h new file mode 100755 index 000000000..ea6859ff0 --- /dev/null +++ b/ps/pt0002100a.h @@ -0,0 +1,7 @@ +// campi della maschera pt002100a Importazione Clienti/Fornitori da file CSV + +#define F_CODDITTA 101 +#define F_RAGSOC 102 +#define F_PATH 103 +#define F_NAME 104 +#define F_TIPO 105 diff --git a/ps/pt0002100a.uml b/ps/pt0002100a.uml new file mode 100755 index 000000000..19d0e30c6 --- /dev/null +++ b/ps/pt0002100a.uml @@ -0,0 +1,67 @@ +#include "pt0002100a.h" + +PAGE "Importazione clienti/fornitori da file" -1 -1 78 12 + +GROUPBOX DLG_NULL 76 3 +BEGIN + PROMPT 2 1 "@bDitta corrente" +END + +NUMBER F_CODDITTA 5 +BEGIN + PROMPT 3 2 "Codice " + FLAGS "FD" + USE LF_NDITTE + INPUT CODDITTA F_CODDITTA + OUTPUT F_RAGSOC RAGSOC + CHECKTYPE REQUIRED +END + +STRING F_RAGSOC 50 +BEGIN + PROMPT 23 2 "" + FLAGS "D" +END + +GROUPBOX DLG_NULL 76 4 +BEGIN + PROMPT 2 4 "@bSorgente" +END + +STRING F_PATH 256 39 +BEGIN + PROMPT 3 5 "Cartella " + DSELECT + CHECKTYPE REQUIRED + FIELD ClifoInPath +END + +STRING F_NAME 18 +BEGIN + PROMPT 3 6 "File " + FIELD ClifoInFile +END + +RADIOBUTTON F_TIPO 1 32 +BEGIN + PROMPT 2 8 "@bDati da Importare" + ITEM "C|Clienti" + ITEM "F|Fornitori" + FLAGS "Z" +END + +BUTTON DLG_ELABORA 10 2 +BEGIN + PROMPT -12 -1 "" + PICTURE BMP_ELABORA + MESSAGE EXIT,K_ENTER +END + +BUTTON DLG_QUIT 10 2 +BEGIN + PROMPT -22 -1 "" +END + +ENDPAGE + +ENDMASK \ No newline at end of file diff --git a/ps/pt0002conf.ini b/ps/pt0002conf.ini new file mode 100755 index 000000000..28f466652 --- /dev/null +++ b/ps/pt0002conf.ini @@ -0,0 +1,6 @@ +[MAIN] +CODDITTA = +RAGSOC = +PATH = +NAME = +TIPO = \ No newline at end of file diff --git a/sv/sv1200.cpp b/sv/sv1200.cpp index aa933c3da..e342080cf 100755 --- a/sv/sv1200.cpp +++ b/sv/sv1200.cpp @@ -397,6 +397,7 @@ class TStampa_stat : public TPrint_application bool _st_tota; // flag stampa totali di "anno" bool _st_val; // Stampa valori bool _st_qta; // Stampa quantita' + bool _st_um; // Stampa UM bool _st_uni; // Stampa valori/quantita' TString16 _valid_types;// Stringa contenente i tipi di riga da stampare // ****************** @@ -1068,6 +1069,16 @@ int TStampa_stat::set_rows_colonne(int row, const TRectype &strec) colval = valun; } + TString80 colstr = colval.string(PICT); + + if (t == 1 && _st_um) + { + TString4 um; + um << " "; + um << strec.get("UMQTA"); + colstr.overwrite(um, 0); + } + int offset = (t - 1) * 3; if (offset >= 0) position += _larg[offset + 0] + _larg[offset + 1] + _larg[offset + 2]; @@ -1075,41 +1086,43 @@ int TStampa_stat::set_rows_colonne(int row, const TRectype &strec) switch (strec.get_char(SVS_TIPO)) { - case LINEA_DATI: - last_data=strec; - set_row_atpos('R',row,colval.string(PICT),position); - break; - case LINEA_RAFFRONTI: - switch (printmask().get(F_TIPORAFFRONTO)[0]) - { - case COMP_AS_VALUE: - set_row_atpos('R',row, colval.string(PICT),position); - break; - case COMP_AS_DIFF: - if (t < 2) + case LINEA_DATI: + last_data=strec; + set_row_atpos('R',row,colstr,position); + break; + case LINEA_RAFFRONTI: + switch (printmask().get(F_TIPORAFFRONTO)[0]) + { + case COMP_AS_VALUE: + set_row_atpos('R',row, colstr,position); + break; + case COMP_AS_DIFF: + if (t < 2) + { + set_row_atpos('R',row, colstr,position); + set_row_atpos('R',row,((real)(last_data.get_real(colname)-strec.get_real(colname))).string(PICT),position + _larg[offset]); + } + break; + case COMP_AS_PERC: + if (t < 2) + { + set_row_atpos('R', row, colstr, position); + if (!colval.is_zero()) { - set_row_atpos('R',row, colval.string(PICT),position); - set_row_atpos('R',row,((real)(last_data.get_real(colname)-strec.get_real(colname))).string(PICT),position + _larg[offset]); + real p = CENTO * (last_data.get_real(colname) - colval) / colval; p.round(1); + set_row_atpos('R',row,p.string(PICTURE_PERCENT),position + _larg[offset] ); } - break; - case COMP_AS_PERC: - if (t < 2) - { - set_row_atpos('R',row, colval.string(PICT),position); - if (!colval.is_zero()) - { - real p = 100.0 * (last_data.get_real(colname) - colval) / colval; p.round(1); - set_row_atpos('R',row,p.string(PICTURE_PERCENT),position + _larg[offset] ); - } - aggiungi_perc=FALSE; - } - break; - } - break; - case LINEA_TARGET: // v2.0 - set_row_atpos('R',row,colval.string(PICT),position); - break; - } + aggiungi_perc=FALSE; + } + break; + } + break; + case LINEA_TARGET: // v2.0 + set_row_atpos('R',row,colstr,position); + break; + default: + break; + } if (t < 2 && strec.get_char(SVS_TIPO) == LINEA_DATI) { @@ -1117,7 +1130,7 @@ int TStampa_stat::set_rows_colonne(int row, const TRectype &strec) if (_st_totr && aggiungi_perc && !tot_riga.is_zero()) { const int pos = position + _larg[offset] + _larg[offset + 1]; - real p = 100.0 * colval / tot_riga; p.round(1); + real p = CENTO * colval / tot_riga; p.round(1); set_row_atpos('R',row,p.string(PICTURE_PERCENT),pos); } // riga con i totali di colonna @@ -1127,7 +1140,7 @@ int TStampa_stat::set_rows_colonne(int row, const TRectype &strec) const real tot = _rec_totale.get_real(colname); if (!tot.is_zero()) { - real p = 100.0 * colval / tot; p.round(1); + real p = CENTO * colval / tot; p.round(1); r_totc = p.string(PICTURE_PERCENT); set_row_atpos('R',row+1,(const char *)r_totc,position+_largcol-LARG_COLPERC); } @@ -1376,6 +1389,7 @@ bool TStampa_stat::menu(MENU_TAG ) _numcol_dati = m.get_int(F_PERIODO); _st_val = m.get_bool(F_STAMPA_VAL); _st_qta = m.get_bool(F_STAMPA_QTA); + _st_um = _st_qta && m.get_bool(F_STAMPA_UM); _st_uni = m.get_bool(F_STAMPA_UNI); _valid_types = ""; diff --git a/sv/sv1200a.h b/sv/sv1200a.h index 583b0c7d7..3ba1dec09 100755 --- a/sv/sv1200a.h +++ b/sv/sv1200a.h @@ -21,6 +21,7 @@ #define F_TIPOART2 224 #define F_TIPOART3 225 #define F_TIPOART4 226 +#define F_STAMPA_UM 227 #define S_CAMPO 101 diff --git a/sv/sv1200a.uml b/sv/sv1200a.uml index 85ec35073..467bc53c3 100755 --- a/sv/sv1200a.uml +++ b/sv/sv1200a.uml @@ -178,11 +178,18 @@ END BOOLEAN F_STAMPA_QTA BEGIN PROMPT 32 13 "Stampa quantita'" + MESSAGE FALSE CLEAR,F_STAMPA_UM + MESSAGE TRUE ENABLE,F_STAMPA_UM +END + +BOOLEAN F_STAMPA_UM +BEGIN + PROMPT 32 14 "Stampa Unita' Misura" END BOOLEAN F_STAMPA_UNI BEGIN - PROMPT 32 14 "Stampa valori unitari" + PROMPT 32 15 "Stampa valori unitari" END LIST F_TIPOCALC 1 11 diff --git a/tc/tc0300.cpp b/tc/tc0300.cpp index 14f664185..ee0910488 100755 --- a/tc/tc0300.cpp +++ b/tc/tc0300.cpp @@ -2,8 +2,10 @@ #include #include #include +#include #include +#include "../include/attiv.h" #include "../include/mov.h" #include "../cg/cglib01.h" #include "tcconf.h" @@ -58,10 +60,55 @@ void TTS_confditta::load_mask() { TConfig_application::load_mask(); TConfig& config = *get_config(); - TSheet_field& si = mask->sfield(F_SHEET_IVA); + TSheet_field& sa = mask->sfield(F_SHEET_ATTIV); + TAssoc_array ditte; const bool use_pcn = config.get_bool("TSUSECMPCN"); int i = 0; + for (i = 0; config.exist("TSDATT", i); i++) + { + const TString8 att(config.get("TSDATT", NULL, i)); + const TString8 ditta(config.get("TSDDITTA", NULL, i)); + + if (att.full()) + ditte.add(att, ditta); + TToken_string& row = sa.row(i); + + row.add(att); + + const TString & descr = cache().get("%AIS", att, "S0"); + + row.add(descr); + row.add(ditta); + sa.check_row(i); + } + + TString query; + const long firm = mask->get_long(F_CODDITTA); + + query.format("USE %d SELECT ATTPREV!=\"X\"\nFROM CODDITTA=%ld\nTO CODDITTA=%ld\n", LF_ATTIV, firm, firm); + TISAM_recordset attrec(query); + + for (bool ok = attrec.move_first(); ok; ok = attrec.move_next()) + + { + const TString8 codatt = attrec.get(ATT_CODATT).as_string(); + if (ditte.objptr(codatt) == NULL) + { + TToken_string& row = sa.row(i); + + row.add(codatt); + + const TString & descr = cache().get("%AIS", codatt, "S0"); + + row.add(descr); + row.add(""); + sa.check_row(i); + } + } + + TSheet_field& si = mask->sfield(F_SHEET_IVA); + si.set_notify(sh_notify); for (i = 0; config.exist("TSGIVA", i); i++) @@ -137,6 +184,20 @@ void TTS_confditta::save_mask(bool tosave) TConfig& config = *get_config(); int i = 0; + for (i = 0; config.exist("TSGIVA", i); i++) + { + config.remove("TSDATT", i); + config.remove("TSDITTA", i); + } + + TSheet_field& sa = m.sfield(F_SHEET_ATTIV); + + FOR_EACH_SHEET_ROW(sa, jd, rowd) + { + config.set("TSDATT", rowd->get(0), NULL, true, jd); + config.set("TSDDITTA", rowd->get(2), NULL, true, jd); + } + for (i = 0; config.exist("TSGIVA", i); i++) { config.remove("TSGIVA", i); diff --git a/tc/tc0300a.uml b/tc/tc0300a.uml index 122c9bf90..ab5f6204b 100755 --- a/tc/tc0300a.uml +++ b/tc/tc0300a.uml @@ -76,27 +76,42 @@ BEGIN FIELD TSRREG END +BOOLEAN F_RICLCONTI +BEGIN + PROMPT 42 10 "Trascodifica Piano dei conti" + FIELD TSRCONTI +END + BOOLEAN F_RICLCAU BEGIN - PROMPT 42 10 "Trascodifica Causali" + PROMPT 2 12 "Trascodifica Causali" FIELD TSRCAU END -BOOLEAN F_RICLCONTI +NUMBER F_EMCAU 3 BEGIN - PROMPT 2 12 "Trascodifica Piano dei conti" - FIELD TSRCONTI + PROMPT 42 12 "Causale TS per movimenti senza causale " + USE LF_MULTIREL + INPUT COD "TSCAU" + INPUT FIRST F_EMCAU + DISPLAY "Codice" FIRST + DISPLAY "Descrizione@60" DATA + DISPLAY "Causale Collegata" SECOND + OUTPUT F_EMCAU FIRST + CHECKTYPE REQUIRED + FLAGS "Z" + FIELD TSREMCAU END BOOLEAN F_RICLVALUTE BEGIN - PROMPT 42 12 "Trascodifica valute" + PROMPT 2 14 "Trascodifica valute" FIELD TSRVAL END BOOLEAN F_NOHCLI BEGIN - PROMPT 2 14 "Non trasferire il cod.cliente di testata" + PROMPT 42 14 "Non trasferire il cod.cliente di testata" FIELD TSRNOHCLI END @@ -112,22 +127,40 @@ BEGIN FIELD TSUSECMPCN END +BOOLEAN F_PROFESS +BEGIN + PROMPT 2 18 "Professionista" + FIELD TSPROFESS +END + BOOLEAN F_RIPRISTINO BEGIN - PROMPT 2 18 "Ripristina alla data" + PROMPT 2 19 "Ripristina alla data" MESSAGE FALSE DISABLE,F_ULTINVIO MESSAGE TRUE ENABLE,F_ULTINVIO END DATE F_ULTINVIO BEGIN - PROMPT 42 18 "Data ultimo invio " + PROMPT 42 19 "Data ultimo invio " FIELD TSULTINV FLAGS "D" END ENDPAGE +PAGE "Attivita' aggiuntive" -1 -1 0 0 + +SPREADSHEET F_SHEET_ATTIV +BEGIN + PROMPT 0 2 "Attivitą Aggiuntive" + ITEM "Codice Attivitą " + ITEM "Descrizione @50" + ITEM "Ditta TeamSystem" +END + +ENDPAGE + PAGE "Configurazione conti IVA" -1 -1 0 0 SPREADSHEET F_SHEET_IVA @@ -156,6 +189,40 @@ ENDPAGE ENDMASK +PAGE "" -1 -1 80 11 + +STRING FR_ATTIV 5 +BEGIN + PROMPT 2 2 "Codice attivitą " + FLAGS "UZD" +END + +STRING FR_DESCR 50 +BEGIN + PROMPT 2 4 "Descrizione " + FLAGS "D" +END + +NUMBER FR_DITTATS 5 +BEGIN + PROMPT 2 6 "Ditta TeamSystem " + FLAGS "Z" +END + +BUTTON DLG_OK 10 2 +BEGIN + PROMPT -12 -1 "" +END + +BUTTON DLG_CANCEL 10 2 +BEGIN + PROMPT -22 -1 "" +END + +ENDPAGE + +ENDMASK + PAGE "" -1 -1 68 11 BOOLEAN SI_SELECTOR diff --git a/tc/tc0700.cpp b/tc/tc0700.cpp index 453f686a7..3b924aead 100755 --- a/tc/tc0700.cpp +++ b/tc/tc0700.cpp @@ -204,10 +204,22 @@ const TRecordset& TTS_campo_sender::clirecset(const char tipocf, const long codc bool TTS_campo_sender::test_swap(const TRecordset& mov) { TRecordset & rmov = rmovrecset(mov); + + bool ok = rmov.move_first(); + char sez = rmov.get(RMV_SEZIONE).as_string()[0]; - rmov.move_first(); + if (rmov.get(RMV_TIPOC).as_string().blank()) + { + for (; ok; ok = rmov.move_next()) + { + if (rmov.get(RMV_TIPOC).as_string().full()) + { + sez = rmov.get(RMV_SEZIONE).as_string()[0]; + break; + } + } + } - const char sez = rmov.get(RMV_SEZIONE).as_string()[0]; const bool vendite = mov.get(MOV_TIPO).as_string()[0] != 'F'; const bool s = vendite ^ (sez == 'D'); @@ -284,8 +296,9 @@ TMask & TTS_campo_sender::get_mask() bool TTS_campo_sender::find_regolarizzazione(TRecordset& mov) { bool found = false; + const TRectype& caus = cache().get(LF_CAUSALI, mov.get(MOV_CODCAUS).as_string()); - const TString16 causreg = caus.get(CAU_CODCAUREG); + const TString4 causreg = caus.get(CAU_CODCAUREG); real totdoc = mov.get(MOV_TOTDOC).as_real(); const real ritfis = mov.get(MOV_RITFIS).as_real(); const real ritsoc = mov.get(MOV_RITSOC).as_real(); @@ -302,19 +315,19 @@ bool TTS_campo_sender::find_regolarizzazione(TRecordset& mov) if (test_swap(mov)) totdoc = -totdoc; - const TRecordset & cli = clirecset(mov.get(MOV_TIPO).as_string()[0], mov.get(MOV_CODCF).as_int()); + const TRecordset& cli = clirecset(mov.get(MOV_TIPO).as_string()[0], mov.get(MOV_CODCF).as_int()); const TString16 paiv = cli.get(CLI_PAIV).as_string(); const TString16 cf = cli.get(CLI_COFI).as_string(); for (bool ok = mov.move_next(); ok && ! found; ok = mov.move_next()) { const TRectype& caus = cache().get(LF_CAUSALI, mov.get(MOV_CODCAUS).as_string()); - const TString16 cod = caus.get(CAU_CODCAUS); + const TString4 cod = caus.get(CAU_CODCAUS); found = (causreg.full() && cod == causreg) || (causreg.blank() && (_caus_regolarizzazione.objptr(cod) || caus.get_bool(CAU_SOLOIVA))); found &= (totdoc == mov.get(MOV_TOTDOC).as_real()); - const TRecordset & clireg = clirecset(mov.get(MOV_TIPO).as_string()[0], mov.get(MOV_CODCF).as_int()); + const TRecordset& clireg = clirecset(mov.get(MOV_TIPO).as_string()[0], mov.get(MOV_CODCF).as_int()); found &= ((paiv.full() && paiv == clireg.get(CLI_PAIV).as_string()) || (paiv.blank() && cf == clireg.get(CLI_COFI).as_string())); if (found) @@ -376,7 +389,7 @@ bool search_reg(const TRelation& rel, void* pJolly) const bool solaiva = rel.lfile().get_bool(CAU_SOLOIVA); const TString codcaus = rel.lfile().get(CAU_CODCAUREG); - if (solaiva || codcaus.full()) + if (codcaus.full()) _caus_regolarizzazione->add(codcaus, codcaus); return true; @@ -397,9 +410,11 @@ bool TTS_campo_sender::create() bool big_cli_code = false; clifo.put(CLI_TIPOCF, "C"); - clifo.put(CLI_CODCF, 100000L);; + clifo.put(CLI_CODCF, 100000L); - if (clifo.read(_isgteq) != _iseof || clifo.get(CLI_TIPOCF) == "F") + + + if (!((clifo.read(_isgteq) == _iseof) || (clifo.get(CLI_TIPOCF) == "F"))) big_cli_code = true; if (!big_cli_code) { @@ -410,7 +425,7 @@ bool TTS_campo_sender::create() big_cli_code = true; } - if (!big_cli_code) + if (big_cli_code) riclassifica().add("TSNOHCLI", EMPTY_STRING); return ok; diff --git a/tc/tc0701.cpp b/tc/tc0701.cpp index 65586c584..5dbae8167 100755 --- a/tc/tc0701.cpp +++ b/tc/tc0701.cpp @@ -6,12 +6,8 @@ #include #include -//#include -//#include #include #include -//#include -//#include #include #include #include @@ -286,8 +282,7 @@ TTS_textset::TTS_textset(const char* query) TString80 field; // dati iva - int i = 0; - for (i = 0; i<8; i++) + for (int i=0; i<8; i++) { field.format("TRF-IMPONIB_%d", i); add_field("0", field, 12, n, 475+(31*i)); // imponibile @@ -305,7 +300,7 @@ TTS_textset::TTS_textset(const char* query) add_field("0", "TRF-TOT-FATT", 12, n, 723); // totale fattura // conti di ricavo/costo - for (i = 0; i < 8; i++) + for (i=0; i<8; i++) { field.format("TRF-CONTORIC_%d", i); add_field("0", field, 7, n, 735+(19*i)); // codice conto di ricavo/costo @@ -320,7 +315,7 @@ TTS_textset::TTS_textset(const char* query) add_field("0", "TRF-CAU-AGG-2-PAGAM", 34, an, 939); // ulteriore descrizione aggiuntiva // altri movimenti - for (i = 0; i < 80; i++) + for (i=0; i<80; i++) { field.format("TRF-CONTO_%d", i); add_field("0", field, 7, n, 973+(64*i)); // codice conto @@ -339,7 +334,7 @@ TTS_textset::TTS_textset(const char* query) } // ratei e risconti - for (i = 0; i < 10; i++) + for (i=0; i<10; i++) { field.format("TRF-RIFER-TAB_%d", i); add_field("0", field, 1, an, 6093+(19*i)); // tabella di riferimento @@ -359,7 +354,7 @@ TTS_textset::TTS_textset(const char* query) add_field("0", "TRF-AN-TIPO-SOGG", 1, n, 6290); // tipo soggetto ritenuta di acconto // ulteriori dati ev. pagamento o movimenti diversi - for (i = 0; i < 80; i++) + for (i=0; i<80; i++) { field.format("TRF-EC-PARTITA-SEZ-PAG_%d", i); add_field("0", field, 2, n, 6291+(2*i)); // numero sezionale partita estratto conto @@ -375,13 +370,13 @@ TTS_textset::TTS_textset(const char* query) add_field("0", "TRF-RIT-4", 12, n, 6526); // 4 // ulteriori dati per unita' produttive ricavi - for (i = 0; i < 8; i++) + for (i=0; i<8; i++) { field.format("TRF-UNITA-RICAVI_%d", i); add_field("0", field, 2, n, 6538+(2*i)); // } // ulteriori dati per unita' produttive pagamenti - for (i = 0; i < 80; i++) + for (i=0; i<80; i++) { field.format("TRF-UNITA-PAGAM_%d", i); add_field("0", field, 2, n, 6554+(2*i)); // @@ -553,21 +548,21 @@ void TTS_sender::remove_last() _tsfile->move_last(); } -bool TTS_sender::add_optional_rec(bool rec_to_add) +bool TTS_sender::add_optional_rec(TRecordset& mov, bool rec_to_add) { if (rec_to_add) { new_rec("1"); - set("TRF1-DITTA", _dittamulti); + set("TRF1-DITTA", dittamulti(mov)); } return false; } bool TTS_sender::add_regol(TRecordset& mov, bool rec_to_add) { - rec_to_add = add_optional_rec(rec_to_add); + rec_to_add = add_optional_rec(mov, rec_to_add); - TString4 codval = mov.get(MOV_CODVALI).as_string(); + TString16 codval = mov.get(MOV_CODVALI).as_string(); real corrvaluta = mov.get(MOV_CORRVALUTA).as_real(); if (codval.blank()) @@ -577,32 +572,34 @@ bool TTS_sender::add_regol(TRecordset& mov, bool rec_to_add) } codval = scod2ricl("TSVAL", codval); set("TRF-COD-VAL", codval); - if (mov_intra(mov)) + + const bool is_intra = mov_intra(mov); + if (is_intra) { corrvaluta *= CENTO; set("TRF-TOTVAL", corrvaluta); } - const TRecnotype pos = mov.current_row(); + const TRecnotype pos = mov.current_row(); // Salva la posizione if (find_regolarizzazione(mov)) { set("TRF-NUM-AUTOFATT", mov.get(MOV_PROTIVA).as_int()); - TString4 codice = scod2ricl("TSREG", mov.get(MOV_REG)); + const TString16 codice = scod2ricl("TSREG", mov.get(MOV_REG)); const long codreg = atol(codice.mid(1)); - set("TRF-SERIE-AUTOFATT", codreg); } else { - if (mov_intra(mov)) - log(2, TR("Manca la regolarizzazion del movimento intra")); + if (is_intra) + log(2, TR("Manca la regolarizzazione del movimento intra")); else - log(2, TR("Manca la regolarizzazion del movimento reverse charge")); + log(2, TR("Manca la regolarizzazione del movimento reverse charge")); } - mov.move_to(pos); + mov.move_to(pos); // Ripristina posizione + return rec_to_add; } @@ -618,6 +615,28 @@ void TTS_sender::add_ratei_risconti(const TRecordset& mov) { } +const TString & TTS_sender::dittamulti(const TRecordset& mov) const +{ + if (multi_activity()) + { + const TString4 codice(mov.get(MOV_REG).as_string()); + + if (codice.full()) + { + int annoiva = mov.get(MOV_DATAREG).as_date().year(); + TString16 key; + + key.format("%04d%s", annoiva, (const char *) codice); + const TString8 attivita = cache().get("REG", key, "S8"); + const TString * ditta = (const TString * )_dittemulti.objptr(attivita); + + if (ditta != NULL) + return *ditta; + } + } + return _dittamulti; +} + void TTS_sender::add_new_rec(const TRecordset& mov) { set("TRF-80-SEGUENTE", "S"); @@ -631,6 +650,9 @@ void TTS_sender::add_new_rec(const TRecordset& mov) void TTS_sender::add_diversi(const TRecordset& mov, const bool moviva) { const bool vendite = mov.get(MOV_TIPO).as_string()[0] != 'F'; + const TString16 codice = scod2ricl("TSREG", mov.get(MOV_REG)); + const bool corrispettivo = codice[0] == 'C'; + long contoclifor = 0L; char seznor = ' '; @@ -667,7 +689,7 @@ void TTS_sender::add_diversi(const TRecordset& mov, const bool moviva) { if (as400) { - if (t > ' ' && first_cli) + if ((t > ' ' || corrispettivo) && first_cli) { first_cli = false; contoclifor = contoricl; @@ -677,7 +699,11 @@ void TTS_sender::add_diversi(const TRecordset& mov, const bool moviva) if (_contiiva.is_key(key)) continue; if (_contirit.is_key(key)) + { riga_ritenute = true; + if (_professionista && vendite) + _rit_acc += rmov.get(RMV_IMPORTO).as_real(); + } else { if (k < 8) @@ -737,29 +763,39 @@ void TTS_sender::add_diversi(const TRecordset& mov, const bool moviva) first_cli = false; if (!(riga_ritenute && intra_rev)) { - field.format("TRF-CONTO_%d", j); - set(field, contoricl); - field.format("TRF-IMPORTO_%d", j); - set(field, rmov.get(RMV_IMPORTO)); - field.format("TRF-DA_%d", j); - set(field, rmov.get(RMV_SEZIONE)); - j++; - if (riga_ritenute) + if (!_professionista || !vendite) { - if (contoclifor > 0L) + field.format("TRF-CONTO_%d", j); + set(field, contoricl); + field.format("TRF-IMPORTO_%d", j); + set(field, rmov.get(RMV_IMPORTO)); + field.format("TRF-DA_%d", j); + set(field, rmov.get(RMV_SEZIONE)); + field.format("TRF-CAU-AGGIUNT_%d", j); + set(field, rmov.get(RMV_DESCR).as_string().left(18)); + j++; + if (riga_ritenute) { - field.format("TRF-CONTO_%d", j); - set(field, contoclifor); - field.format("TRF-IMPORTO_%d", j); - set(field, rmov.get(RMV_IMPORTO)); - field.format("TRF-DA_%d", j); - const TString4 sez = rmov.get(RMV_SEZIONE).as_string() == "D" ? "A" :"D"; - set(field, sez); - j++; + if (contoclifor > 0L) + { + field.format("TRF-CONTO_%d", j); + set(field, contoclifor); + field.format("TRF-IMPORTO_%d", j); + set(field, rmov.get(RMV_IMPORTO)); + field.format("TRF-DA_%d", j); + const TString4 sez = rmov.get(RMV_SEZIONE).as_string() == "D" ? "A" :"D"; + set(field, sez); + field.format("TRF-CAU-AGGIUNT_%d", j); + set(field, rmov.get(RMV_DESCR).as_string().left(18)); + j++; + } + else + log(2, "Conto cliente/formitore non trovato per giroconto ritenute o intra o reverse charge"); } - else - log(2, "Conto cliente/formitore non trovato per giroconto ritenute o intra o reverse charge"); } + else + set("TRF-RIT-ACC", _rit_acc); + } valid_rec = true; } @@ -780,7 +816,7 @@ void TTS_sender::add_conti_ricavo_costo(const TRecordset& mov) return; TRecordset & riva = rivarecset(mov); - TString codice = scod2ricl("TSREG", mov.get(MOV_REG)); + TString16 codice = scod2ricl("TSREG", mov.get(MOV_REG)); const bool corrispettivo = codice[0] == 'C'; int i = 0, j = 0; real fattore = UNO; @@ -805,7 +841,6 @@ void TTS_sender::add_conti_ricavo_costo(const TRecordset& mov) if (riva.get(RMI_IMPOSTA).is_zero()) { TCodiceIVA c(riva.get(RMI_CODIVA).as_string()); - c.scorpora(imponibile); } } @@ -851,6 +886,7 @@ void TTS_sender::add_conti_ricavo_costo(const TRecordset& mov) void TTS_sender::add_tot_fattura(const TRecordset& mov) { + const bool vendite = mov.get(MOV_TIPO).as_string()[0] != 'F'; real totdoc = mov.get(MOV_TOTDOC).as_real(); const real ritfis = mov.get(MOV_RITFIS).as_real(); const real ritsoc = mov.get(MOV_RITSOC).as_real(); @@ -867,12 +903,16 @@ void TTS_sender::add_tot_fattura(const TRecordset& mov) if (test_swap(mov)) totdoc = -totdoc; set("TRF-TOT-FATT", totdoc); + + if (_professionista && vendite) + set("TRF-RIT-ACC", ritfis); + _rit_acc = ZERO; } void TTS_sender::add_datiiva(const TRecordset& mov) { TRecordset & rmoviva = rivarecset(mov); - TString codice = scod2ricl("TSREG", mov.get(MOV_REG)); + TString16 codice = scod2ricl("TSREG", mov.get(MOV_REG)); const bool corrispettivo = codice[0] == 'C'; int i = 0, j = 0; real fattore = UNO; @@ -950,13 +990,23 @@ void TTS_sender::add_datiiva(const TRecordset& mov) void TTS_sender::add_header(const TRecordset& mov, const bool fullhesd) { const bool moviva = !mov.get(MOV_REG).is_empty(); - const long codcaus = cod2ricl("TSCAU", mov.get(MOV_CODCAUS)); + const TString8 src_caus(mov.get(MOV_CODCAUS).as_string()); + const long codcaus = src_caus.full() ? cod2ricl("TSCAU", src_caus) : _empty_caus; // dati obbligatori - set("TRF-DITTA", _dittamulti); + set("TRF-DITTA", dittamulti(mov)); set("TRF-CAUSALE", codcaus); - TString descaus(decode_causale(mov)); - set("TRF-CAU-DES", descaus.left(15)); + + const TString descaus(decode_causale(mov)); + + set("TRF-CAU-DES", descaus.left(15)); + if (!moviva) + set("TRF-CAU-AGG", descaus.mid(15)); + + const TString & desc = mov.get(MOV_DESCR).as_string(); + + set("TRF-CAU-AGG-1", desc.left(34)); + set("TRF-CAU-AGG-2", desc.mid(34)); const TDate datareg(mov.get(MOV_DATAREG).as_string()); @@ -967,7 +1017,7 @@ void TTS_sender::add_header(const TRecordset& mov, const bool fullhesd) set("TRF-DATA-DOC", datadoc.string(full, '\0')); TString numdoc(mov.get(MOV_NUMDOC).as_string()); - TString codice = moviva ? scod2ricl("TSREG", mov.get(MOV_REG)) : EMPTY_STRING; + TString16 codice = moviva ? scod2ricl("TSREG", mov.get(MOV_REG)) : EMPTY_STRING; numdoc.left(6); if (numdoc.full()) @@ -1261,6 +1311,18 @@ void TTS_sender::set_parameters() TConfig configtc(CONFIG_DITTA, "tc"); _dittamulti = configtc.get("TSDitta"); + _professionista = configtc.get_bool("TSPROFESS"); + + for (int j = 0; configtc.exist("TSDATT", j); j++) + { + const TString8 att(configtc.get("TSDATT", NULL, j)); + const TString8 ditta(configtc.get("TSDDITTA", NULL, j)); + + if (att.full()) + _dittemulti.add(att, ditta); + } + + _empty_caus = configtc.get_long("TSREMCAU"); TAssoc_array& tab = configtc.list_variables(); diff --git a/tc/tc0701.h b/tc/tc0701.h index fa6affb76..e16d71dfe 100755 --- a/tc/tc0701.h +++ b/tc/tc0701.h @@ -19,10 +19,14 @@ class TTS_sender : public TSkeleton_application TLog_report* _log; bool _errors_logged; TString8 _dittamulti; + TAssoc_array _dittemulti; + long _empty_caus; TArray _recsets; TAssoc_array _iva; TAssoc_array _contiiva; TAssoc_array _contirit; + bool _professionista; + real _rit_acc; protected: TRecordset * get_recset(const int logicnum) const { return (TRecordset *) _recsets.objptr(logicnum);} @@ -48,7 +52,7 @@ protected: void add_ratei_risconti(const TRecordset& mov); void add_ulteriori(TRecordset& mov); bool add_regol(TRecordset& mov, bool rec_to_add); - bool add_optional_rec(bool rec_to_add); + bool add_optional_rec(TRecordset& mov, bool rec_to_add); const TString & scod2ricl(const char* tab, const TString& cod); const TString & scod2ricl(const char* tab, const TVariant& cod); const long cod2ricl(const char* tab, const TString& cod); @@ -74,8 +78,8 @@ protected: public: void log(int sev, const char* msg); - - TString & dittamulti() { return _dittamulti;} + virtual bool multi_activity() const { return true; } + const TString & dittamulti(const TRecordset& mov) const ; TAssoc_array & riclassifica() {return _riclassifica;} virtual void postprocess_movs(TRecordset & mov) {} diff --git a/tc/tc9.cpp b/tc/tc9.cpp index 29b1a063d..6e4d29eb6 100755 --- a/tc/tc9.cpp +++ b/tc/tc9.cpp @@ -7,8 +7,8 @@ int main(int argc, char** argv) const int op = argc < 2 ? 0 : argv[1][1]-'0'; switch (op) { - case 0: tc9100(argc,argv); break; // Invio a Proforma - case 1: tc9200(argc,argv); break; // Invio a Sispac/Cosmo + case 0: tc9100(argc,argv); break; // esiste sulla 4.0 Invio a Proforma + case 1: tc9200(argc,argv); break; // esiste dalla 4.0 Invio a Sispac/Cosmo default: tc9100(argc,argv); break; } exit(0); diff --git a/tc/tc9100.cpp b/tc/tc9100.cpp index 4846ae79d..1673b64b7 100755 --- a/tc/tc9100.cpp +++ b/tc/tc9100.cpp @@ -1,1626 +1,7 @@ -#include -#include -#include -#include -#include -#include - +//NON riportare nulla!!!! Esiste dalla 4.0; qui e' solo un segnaposto #include "tc9.h" -#include "tc9100a.h" - -#include -#include - -#include "../cg/cg2101.h" -#include "../cg/cg2103.h" -#include "../cg/cgsaldac.h" - -#include "../ca/calib01.h" -#include "../ca/movana.h" -#include "../ca/rmovana.h" -#include "../ve/velib.h" - -#include -#include - - -class TInvioP_file: public TFile_text -{ -protected: - virtual void validate(TCursor& cur,TRecord_text &rec, TToken_string &val, TString& str); - -public: - TInvioP_file(const TString& file_name); - virtual ~TInvioP_file() { } -}; - -TInvioP_file::TInvioP_file(const TString& file_name) - : TFile_text(file_name, "tc9100a.ini") -{ -} - -////////////////////////////////////////////////////// -// MASCHERA -////////////////////////////////////////////////////// - -class TInvioP_mask : public TAutomask -{ -protected: - bool on_field_event(TOperable_field& o, TField_event e, long jolly); - void config_loader(TSheet_field& sf, const char* paragrafo); - void config_setter(TSheet_field& sf, const char* paragrafo); - -public: - TInvioP_mask(); - virtual ~TInvioP_mask(){}; -}; - -TInvioP_mask::TInvioP_mask() :TAutomask ("tc9100a") -{ - config_loader(sfield(F_PDCC), "Pdcc"); -} - -bool TInvioP_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) -{ - switch (o.dlg()) - { - case F_CODDITTA: - if (e==fe_init && o.empty()) - { - set(F_CODDITTA, main_app().get_firm()); - ((TEdit_field&) o).check(); - disable(F_CODDITTA); - } - break; - case DLG_SAVEREC: - if (e == fe_button) - { - config_setter(sfield(F_PDCC), "Pdcc"); - } - break; - default: - break; - } - return true; -} - -void TInvioP_mask::config_loader(TSheet_field& sf, const char* paragrafo) -{ - //carica file configurazione conti; attenzione!!!il file di configurazione in questione e' il - //medesimo del programma per la stampa del pagato in contabilita' analitica, visto che i due - //programmi necessitano degli stessi conti - TFilename configname = "ca3600a.ini"; - configname.custom_path(); - TConfig configfile(configname, paragrafo); - - TString_array conti; - - int first_enabled_row = -1; - int n = configfile.list_variables(conti, false, paragrafo, true); - FOR_EACH_ARRAY_ROW(conti, i, row) - { - sf.row(-1) = configfile.get(*row); //carica la riga del .ini senza il contatore - sf.check_row(i); - TString pippo = sf.row(i); - pippo = pippo.left(1); //disabilita le righe di tipo C e P che riguardano la sola stampa.. -/* if (pippo == "C" || pippo == "P") //..del pagato - sf.disable_row(i); - else - { - if (first_enabled_row < 0) //se la riga non e' C o P deve incrementare il contatore della.. - first_enabled_row = i; //..prima riga disabilitata - }*/ - } - if (first_enabled_row >= 0) //se il contatore della prima riga disabilitata e' stato.. - sf.select(first_enabled_row); //..incrementato, sposta il focus alla prima riga abile -} - -void TInvioP_mask::config_setter(TSheet_field& sf, const char* paragrafo) -{ - TFilename configname = "ca3600a.ini"; - configname.custom_path(); - TConfig configfile(configname, paragrafo); - - configfile.remove_all(); //svuota il paragrafo sul .ini prima di ricompilarlo (se non si facesse - //non si riuscirebbero ad ammazzare le righe sul .ini - FOR_EACH_SHEET_ROW (sf, i, row) - { - TToken_string conto(""); - conto.add(row->get(0)); - conto.add(row->get(1)); - conto.add(row->get(2)); - conto.add(row->get(3)); - - configfile.set("conto", conto, NULL, true, i); - } -} - -////////////////////////////////////////////// -// STRUCT (saldo di 1 conto) -////////////////////////////////////////////// -struct TInvioP_saldo : public TObject -{ - TString16 _zio; - TImporto _importo; - - TInvioP_saldo(const TRectype& r); - TInvioP_saldo(const TString& zio, const TImporto& importo); -}; - -TInvioP_saldo::TInvioP_saldo(const TRectype& r) -{ - const TBill zio(r); - _zio = zio.string(0x8); - - const char sezione = r.get_char(RMV_SEZIONE); - const real imp = r.get_real(RMV_IMPORTO); - _importo.set(sezione, imp); - _importo.normalize(); -} - -TInvioP_saldo::TInvioP_saldo(const TString& zio, const TImporto& importo) - : _zio(zio), _importo(importo) -{} - - -////////////////////////////////////////////// -// SALDI MOVIMENTO CONTABILE -////////////////////////////////////////////// -class TInvioP_saldi_cg : public TArray -{ -public: - //prende l'oggetto i-esimo (in questo caso un TInvioP_saldo) e ritorna il conto di tale oggetto - const TString& conto(int i) { return ((TInvioP_saldo*)objptr(i))->_zio; } - //stessa roba ma per l'importo - TImporto& importo(int i) { return ((TInvioP_saldo*)objptr(i))->_importo; } - bool sottrai_importo(const TString& conto, const TImporto& importo); - void somma(const TRectype& rmov); - void sottrai(const TRectype& rmovana); -}; - -void TInvioP_saldi_cg::somma(const TRectype& rmov) -{ - TInvioP_saldo* s = new TInvioP_saldo(rmov); - add(s); -} - -bool TInvioP_saldi_cg::sottrai_importo(const TString& zio, const TImporto& imp) -{ - int k; - //caso fortunato - //scandisce gli elementi dell'array;se ne trova uno (k-esimo) con conto ed importo coincidenti.. - //..con quelli passati al metodo, azzera l'importo di tale elemento dell'array - for (k = 0; k < items(); k++) - { - if (conto(k) == zio && importo(k) == imp) - { - importo(k).set('D', ZERO); - return true; - } - } - - //caso sfortunato - //in questo caso gli importi dell'elemento k-esimo dell'array e passato al metodo NON coincidono - TImporto residuo = imp; - int ultima_riga_buona = -1; - - for (k = 0; k < items() && !residuo.is_zero(); k++) - { - if (conto(k) == zio) - { - TImporto& val = importo(k); - residuo.normalize(val.sezione()); - if (residuo >= val) - { - residuo -= val; - val.set('D', ZERO); - } - else - { - val -= residuo; - residuo.set('D', ZERO); - } - ultima_riga_buona = k; - } - } - //alla fine del ciclo sull'array resta un residuo non nullo.. - if (!residuo.is_zero()) - { - residuo.normalize(); - residuo.swap_section(); - if (ultima_riga_buona >= 0) - importo(ultima_riga_buona) += residuo; - } - return true; -} - -void TInvioP_saldi_cg::sottrai(const TRectype& rmovana) -{ - //adesso tocca alle righe contabili senza commessa - const int gruppo = atoi(rmovana.get(RMOVANA_CODCONTO).left(3)); - const int conto = atoi(rmovana.get(RMOVANA_CODCONTO).mid(3,3)); - const long sottoconto = atol(rmovana.get(RMOVANA_CODCONTO).mid(6,6)); - - const TBill zio(gruppo, conto, sottoconto); - - const TImporto importo(rmovana.get_char(RMOVANA_SEZIONE), rmovana.get_real(RMOVANA_IMPORTO)); - sottrai_importo(zio.string(0x8), importo); -} - -////////////////////////////////////////////// -// APPLICAZIONE -////////////////////////////////////////////// - -class TInvioP : public TSkeleton_application -{ - TCursor* _cur; - TInvioP_mask* _msk; - TDate _dataini, _datafin; - long _nregcosto, _nregpag; - real _importo; - char _accsal; - TConfig* _configfile; - TAssoc_array _fiscali,_sociali, _costi, _pagamenti; //array che contengono i conti - -protected: - virtual bool create(void); - virtual bool destroy(void); - virtual void main_loop() ; - void invio_proforma(); - bool i_proforma_movimenti(); - bool i_proforma_righe(TCursor& cur, TInvioP_file* trasfile); - bool i_proforma_pagamenti(); - bool i_proforma_clifor(char tipocf = 'C'); - bool i_proforma_conti(); - - real totale_documento(TMovimentoPN& pn, const bool includi_ritenute = true) const; - void lettura_conti(TAssoc_array& assoc, const char tipoconto); - bool cerca_conto(const TBill& bill, const TAssoc_array& assoc, const char tipoconto) const; - bool cerca_fiscali(const TBill& bill) const; - bool cerca_sociali(const TBill& bill) const; - int cerca_pagamento(const TBill& bill) const; - int cerca_costo(const TBill& bill) const; - bool test_swap(TCausale& caus, bool ritsoc) const; - real calcola_pagamento(TRectype& curpag_rec, real& iva_indetraibile); - bool sottrai_iva(TMovimentoPN& pn, const TRectype& rigaiva); - void stringa_grcosot(TRecord_text& recrighe, const TString& zio); - long calcola_fattura_originale(long nreg) const; - bool calcola_imponibile_totdoc(const long nreg, const TRectype& pag_rec, - real& imponibile, real& totdoc, real& totpagato, real& iva_indetraibile) const; - void calcola_imposte(const real& importo, const real& imposta, - const TString& codind, real& iva_det, real& iva_ind) const; - -public: - const real get_importo() {return _importo;} - const long get_nregcosto() const {return _nregcosto;} - const long get_nregpag() const {return _nregpag;} - const char get_accsal() const {return _accsal;} - const TString& get_vocespesa(const TString& zio) const; - TInvioP_file* apri_file(const char* nome); - void chiudi_file(TInvioP_file* trasfile); - - TInvioP() {}; - virtual ~TInvioP() {}; -}; - -// restituisce un riferimento all' applicazione -inline TInvioP& app() { return (TInvioP&) main_app();} - -// gestione dei messaggi estesi nei campi -void TInvioP_file::validate(TCursor& cur,TRecord_text &rec, TToken_string &s, TString& str) -{ - const TString code(s.get(0)); - TString valore; - if (code == "_FISSO") - { - // gestione dei campi fissi per i record delle riba - // sintassi: _FISSO,! - // dove: č la stringa fissa da emettere - TString in(s.get()); - CHECK(in[0]=='!',"Macro _FISSO senza carattere '!'"); - in.ltrim(1); - in.trim(); - valore = in; - } - else if (code == "_TELEFONO") - { - valore = str; - valore.trim(); - str = cur.curr().get("PTEL"); - valore << str; - valore.trim(); - } - else if (code == "_RAGSOC") - { - valore = str; - valore = valore.strip_double_spaces(); - } - else if (code == "_FLAG") - { - if (app().get_accsal() == 'S') - valore = "S"; - else - valore = "A"; - - } - else if (code == "_NREGCOSTO") - { - valore.format("%ld", app().get_nregcosto()); - } - else if (code == "_NREGPAG") - { - valore.format("%ld", app().get_nregpag()); - } - else if (code == "_IMPORTO") - { - valore = app().get_importo().string(); - } - - else NFCHECK("Macro non definita: %s", (const char *)code); - str = valore; -} - -TInvioP_file* TInvioP::apri_file(const char* nome) -{ - TFilename filename = _msk->get(F_DESTINAZIONE); - filename.add(nome); - filename.ext("txt"); - if (filename.exist()) - remove(filename); - - TInvioP_file* trasfile = new TInvioP_file(filename); - trasfile->open(filename,'w'); - trasfile->force_record_separator(); - return trasfile; -} - -void TInvioP::chiudi_file(TInvioP_file* trasfile) -{ - trasfile->close(); - delete trasfile; -} - -const TString& TInvioP::get_vocespesa(const TString& zio) const -{ - TConfig configfile("tc9100conf.ini", "OPZIONI"); - const TString16 confstringa = configfile.get("CONFSTRINGA"); - const int len = confstringa.len(); - - TLocalisamfile panapdc(LF_PANAPDC); - panapdc.zero(); - panapdc.setkey(2); - panapdc.put("GRUPPO", atoi(zio.mid(0,3))); - panapdc.put("CONTO", atoi(zio.mid(3,3))); - panapdc.put("SOTTOCONTO", atol(zio.mid(6,6))); - const TRectype r(panapdc.curr()); - - for (panapdc.read(); !panapdc.eof(); panapdc.next()) - { - if (panapdc.curr() != r) - break; - const TString& codconto = panapdc.get("CODCONTO"); - if (codconto.starts_with(confstringa)) - return codconto.mid(len); - } - return EMPTY_STRING; -} - -bool TInvioP::i_proforma_conti() -{ - TInvioP_file* trasfile = apri_file("pianocon"); - - TRelation rel(LF_PCON); - TCursor cur(&rel); - const long cur_items = cur.items(); - if (cur_items != 0) - { - TProgind pi(cur_items, "Trasferimento conti...", true, true); - - cur.freeze(); - TRectype& cur_rec = cur.curr(); - for (cur = 0; cur.pos() < cur_items; ++(cur)) - { - pi.addstatus(1); - if (pi.iscancelled()) - break; - - TRecord_text rec; - rec.set_type("P"); - trasfile->autoload(rec, cur); - trasfile->write(rec); - } - } - chiudi_file(trasfile); - return true; -} - -bool TInvioP::i_proforma_movimenti() -{ - TInvioP_file* trasfile = apri_file("registra"); //file testate - TInvioP_file* trasfilerighe = apri_file("righe"); //file righe movimenti - - //trasferimento testate movimenti (cerca direttamente sui movimenti analitici in chiave 2.. - //..,cioč per DATACOMP e con NUMREGCG!=0 - TRectype da(LF_MOV); - TRectype a(LF_MOV); - da.put(MOV_DATAREG, _dataini); - a.put(MOV_DATAREG, _datafin); - TRelation rel(LF_MOV); - rel.add(LF_CAUSALI, "CODCAUS==CODCAUS"); - - TCursor cur(&rel, "", 2, &da, &a); //chiave per data - - const long cur_items = cur.items(); - if (cur_items != 0) - { - //prepara i record di tipo testata da scrivere - TRecord_text rec; - rec.set_type("T"); - - TProgind pi(cur_items, "Trasferimento movimenti...", true, true); - - cur.freeze(); - const TRectype& cur_rec = cur.curr(); - for (cur = 0; cur.pos() < cur_items; ++(cur)) - { - pi.addstatus(1); - if (pi.iscancelled()) - break; - - //carica e scrive il record di testata in base alle informazioni contenute nel tc9100a.ini - trasfile->autoload(rec, cur); - trasfile->write(rec); - //trasferisce le righe del movimento analitico corrente solo - i_proforma_righe(cur, trasfilerighe); - } - } - chiudi_file(trasfilerighe); - chiudi_file(trasfile); - return true; -} - -bool TInvioP::i_proforma_righe(TCursor& cur, TInvioP_file* trasfilerighe) -{ - //---- righe movimenti ---- - TInvioP_saldi_cg conti_importi; - - //Creo un movimento PN (con numreg = a quello del mov)che servira' un po' dovunque - TMovimentoPN pn; - pn.curr() = cur.curr(); - if (pn.read() == NOERR) - { - for (int j = 0; j < pn.cg_items(); j++) - conti_importi.somma(pn.cg(j)); - } - - TRecord_text recrighe; //istanzia il tipo record corretto da scrivere sul trasfilerighe - recrighe.set_type("R"); - - TAnal_mov analmov(cur.curr()); //..istanzia il movimento analitico con numregcg=numreg del mov - const long analrighe_items = analmov.body().rows(); - - if (analrighe_items > 0) //se il movana ha righe.. - { - TRelation rel_rmovana(LF_RMOVANA); //crea una relazione sulle righe anali cui aggiunge mov e movana - rel_rmovana.add(LF_MOVANA, "NUMREG==NUMREG"); - rel_rmovana.add(LF_MOV, "NUMREG==NUMREGCG", 1, LF_MOVANA); - TCursor cur_rmovana(&rel_rmovana); //crea il cursore sulle righe analitiche che serve per poter usare la autoload - cur_rmovana.curr(LF_MOVANA) = analmov; - cur_rmovana.curr(LF_MOV) = cur.curr(); - - for (int i = 1; i <= analrighe_items; i++) - { - //..e scandisce le righe - const TRectype& riga = analmov.body().row(i); - //inganna il cursore passandogli la riga analitica in esame (bastardo!) - cur_rmovana.curr() = riga; - //carica le righe analitiche - trasfilerighe->autoload(recrighe, cur_rmovana); - //toglie le righe contabili corrispondenti che sono appena state aggiunte con la autoload (sarebbero.. - //..duplicate se non lo facesse!!!) - conti_importi.sottrai(riga); - - //procedura orrenda per eliminare gli zeri dai gr/co/sot e passarli come stringhe! - const TString16 zio = cur_rmovana.curr().get(RMOVANA_CODCONTO); - stringa_grcosot(recrighe, zio); - - //procedura per scrivere la fase che deve essere spezzata in due per sottoprogetto ed edizione - const TString& codfase = riga.get(RMOVANA_CODFASE); - if (codfase.full()) - { - recrighe.add(codfase.left(4), 14); - recrighe.add(codfase.mid(4,4), 15); - } - - //procedura per ricavare la voce di spesa - const TString& vocespesa = get_vocespesa(zio); - recrighe.add(vocespesa, 16); - - //scrive sul file di trasferimento (alla faccia della semplicita'!) - trasfilerighe->write(recrighe); - } - } - //prende le righe contabili che non sono state eliminate dalle analitiche nelle sottrai(riga).. - //..in modo da passare anche quelle (in caso contrario sarebbero andati perduti gli importi di.. - //..tali righe che non avevano commessa!) - const long conti_importi_items = conti_importi.items(); - TString workstring; //stringa di lavoro che serve nel ciclo sotto - for (int k = 0; k < conti_importi_items; k++) - { - if (!conti_importi.importo(k).is_zero()) - { - //aggiunge i valori ai campi uno ad uno perchč non ha un cursore per fare l'autoload - recrighe.destroy(); - recrighe.add(pn.curr().get(MOV_NUMREG), 0); //numreg - workstring = "N"; - recrighe.add(workstring, 1); //rigaiva - TImporto& imp = conti_importi.importo(k); - workstring.cut(0) << imp.sezione(); - recrighe.add(workstring, 2); //sezione - //procedura orrenda per eliminare gli zeri dai gr/co/sot e passarli come stringhe! - const TString& zio = conti_importi.conto(k); - stringa_grcosot(recrighe, zio); - - const TString tipocf = pn.curr().get(MOV_TIPO); - recrighe.add(tipocf, 6); //tipocf - - //procedura per stringare il codice clifo - if (tipocf > ' ') - { - const long codcf = pn.curr().get_long(MOV_CODCF); - TString cf; - cf.format("%ld", codcf); - recrighe.add(cf, 7); //codcf - } - else - { - recrighe.add("", 7); //codcf - } - - recrighe.add(pn.curr().get(RMV_DESCR), 8); //descrizione - recrighe.add(imp.valore().string(), 9); //importo - - //procedura per ricavare la voce di spesa - const TString& vocespesa = get_vocespesa(zio); - recrighe.add(vocespesa, 16); - - //e finalmente scrive le righe avanzate... - trasfilerighe->write(recrighe); - } - } - - //---- righe iva ---- - //adesso tocca alle righe iva...e sara' un casino indicibile! - - //assoc array contenente tutti i diversi conti che incontrera' nello scanning delle righe iva - TAssoc_array conti; - //causale del movimento: serve per conoscere il tipo di detraibilita' dell'iva (piu' sotto) - const TCausale caus(pn.curr().get(MOV_CODCAUS)); - const int anno = pn.curr().get_date(MOV_DATAREG).year(); - real imp_detr, iva_detr, imp_indetr, iva_indetr; - - //scanning delle righe iva alla ricerca dei conti che compaiono - for (int l = 0; l < pn.iva_items(); l++) - { - //prende il conto e lo mette nell'assoc_array dei conti (notare che, essendo un assoc_array,.. - //..non vengono inseriti doppioni! mitico!!) - TBill conto; - conto.get(pn.iva(l)); - const char* codconto = conto.string(0x8); - - //ad ogni conto lega un assoc_array (codivae) che conterra' tutti i codici iva legati a quel.. - //..conto nelle righe iva con i relativi importi - TAssoc_array* codivae = (TAssoc_array*) conti.objptr(codconto); - if (codivae == NULL) //se non esiste l'assoc_array legato al conto lo crea - { - codivae = new TAssoc_array; - //aggiunge all'assoc_array conti il suo elemento assoc_array codivae..ha un assoc_array.. - //..di assoc_array! - conti.add(codconto, codivae); - } - - const TString4 codiva = pn.iva(l).get(RMI_CODIVA); //prende il codice iva dalla riga iva - //aggiungere qui eventuale codice intero di indetraibilita' - - //ad ogni codiva presente in codivae lega un importo che risultera' la somma di tutti gli.. - //..importi con lo stesso conto e codice iva - real* tot_imp = (real*) codivae->objptr(codiva); - if (tot_imp == NULL) //se non esiste l'importo legato al codice iva lo crea - { - tot_imp = new real; - //aggiunge all'assoc_array codivae il suo elemento real tot_imp - codivae->add(codiva, tot_imp); - } - - //accresce l'importo tot_imp relativo alla coppia codiva+codconto corrente - const real imponibile = pn.iva(l).get_real(RMI_IMPONIBILE); - const real imposta = pn.iva(l).get_real(RMI_IMPOSTA); - const TString4 codind = pn.iva(l).get(RMI_TIPODET); - pn.analizza_riga_IVA(imponibile, imposta, caus, anno, codiva, codind, imp_detr, - iva_detr, imp_indetr, iva_indetr); - *tot_imp += imp_detr + imp_indetr + iva_indetr; - //aggiungere qui eventuale imposta - } - - TRecord_text recrigheiva; //istanzia il tipo record corretto da scrivere sul trasfilerighe - recrigheiva.set_type("I"); - int nrighe = 0; - - TRelation rel_rmoviva(LF_RMOVIVA); - rel_rmoviva.add(LF_MOV, "NUMREG==NUMREG"); - TCursor cur_rmoviva(&rel_rmoviva); - cur_rmoviva.curr(LF_MOV) = cur.curr(); - - const long analrigheiva_items = analmov.body().rows(); - - for (int n = 1; n <= analrigheiva_items; n++) - { - //scanning delle righe analitiche per estrarne i conti e controllare se compaiono nell'assoc_array.. - //..dei conti riempito con i conti trovati nelle righe iva - const TRectype& riga = analmov.body().row(n); - const TString& codconto = riga.get(RMOVANA_CODCONTO); - TAssoc_array* codivae = (TAssoc_array*) conti.objptr(codconto); //assoc_array codivae del codconto - - //se ha almeno un codice iva associato a questo conto nell'assoc_array dei conti.. - if (codivae != NULL) - { - //..prende l'importo della riga analitica.. - real importo_riga = riga.get_real(RMOVANA_IMPORTO); - //..lo ridistribuisce secondo le percentuali iva - TGeneric_distrib distributore(importo_riga, TCurrency::get_firm_dec()); - - FOR_EACH_ASSOC_OBJECT((*codivae), h, k, imp) - { - const real& imp_iva = *(real*)imp; - distributore.add(imp_iva); - } - - //crea una riga iva dal cursore, con numreg = numreg della testata del mov originale - TRectype& rigaiva = cur_rmoviva.curr(LF_RMOVIVA); - rigaiva.put(RMI_NUMREG, pn.curr().get(MOV_NUMREG)); - - //scan dell'assoc_array ridistribuito e inserimento dei valori nella riga iva appena creata - FOR_EACH_ASSOC_OBJECT((*codivae), hi, ki, impi) - { - rigaiva.put(RMI_NUMRIG, ++nrighe); - rigaiva.put(RMI_GRUPPO, codconto.mid(0,3)); - rigaiva.put(RMI_CONTO, codconto.mid(3,3)); - rigaiva.put(RMI_SOTTOCONTO, codconto.mid(6,6)); - const TBill zio(rigaiva); - rigaiva.put(RMI_TIPOC, zio.tipo()); - rigaiva.put(RMI_IMPONIBILE, distributore.get()); - rigaiva.put(RMI_CODIVA, ki); - - //deve sottrarre gli importi trovati dalle righe iva originali - sottrai_iva(pn, rigaiva); - - //scrittura delle righe di tipo I; notare che il cur passato alla autoload altri non e'.. - //..che la rigaiva appena completata - trasfilerighe->autoload(recrigheiva, cur_rmoviva); - - //procedura ignorante per stringare il codice clifo - if (zio.tipo() > ' ') - { - const long sottoconto = zio.sottoconto(); - TString cf; - cf.format("%ld", sottoconto); - recrigheiva.add(cf, 7); - } - - recrigheiva.add(riga.get(RMOVANA_DESCR).left(40), 8); //descrizione riga iva = riga anale corrente - recrigheiva.add(riga.get(RMOVANA_CODCMS), 13); //commessa presa dalla riga analitica corrente - - //procedura per scrivere la fase che deve essere spezzata in due per sottoprogetto ed edizione - const TString& codfase = riga.get(RMOVANA_CODFASE); - if (codfase.full()) - { - recrighe.add(codfase.left(4), 14); - recrighe.add(codfase.mid(4,4), 15); - } - - //procedura per ricavare la voce di spesa - TString uncle = zio.string(0x8); - const TString& vocespesa = get_vocespesa(uncle); - recrighe.add(vocespesa, 16); - - trasfilerighe->write(recrigheiva); - } - } //if(codivae!=.. - } //for(analmov.rows.. - - const long righeiva_items = pn.iva_items(); - if (righeiva_items > 0) - { - //deve trasferire le righe iva rimaste dopo la sottrazione degli importi dovuti alle righe analitiche - for (int m = 0; m < righeiva_items; m++) - { - const TRectype& riga = pn.iva(m); - if (!riga.get_real(RMI_IMPOSTA).is_zero()) - { - const TBill uncle(riga); - cur_rmoviva.curr() = riga; - trasfilerighe->autoload(recrigheiva, cur_rmoviva); - recrigheiva.add(uncle.tipo(), 6); //tipocf - recrigheiva.add(uncle.descrizione().left(40), 8); //descrizione della riga iva = descrizione conto - //procedura per ricavare la voce di spesa - TString zio = uncle.string(0x8); - const TString& vocespesa = get_vocespesa(zio); - recrighe.add(vocespesa, 14); - trasfilerighe->write(recrigheiva); - } - } - } - return true; -} - -bool TInvioP::sottrai_iva(TMovimentoPN& pn, const TRectype& rigaiva) -{ - const TBill zio(rigaiva); - const real imposta = rigaiva.get_real(RMI_IMPOSTA); - - int k; - //caso fortunato - //scandisce gli elementi dell'array;se ne trova uno (k-esimo) con conto ed importo coincidenti.. - //..con quelli passati al metodo, azzera l'importo di tale elemento dell'array - for (k = 0; k < pn.iva_items(); k++) - { - TRectype& iva_k = pn.iva(k); - const TBill conto_k(iva_k); - const real imposta_k = iva_k.get_real(RMI_IMPOSTA); - if (conto_k == zio && imposta_k == imposta) - { - iva_k.zero(RMI_IMPOSTA); - return true; - } - } - - //caso sfortunato - //in questo caso gli importi dell'elemento k-esimo dell'array e passato al metodo NON coincidono - real residuo = imposta; - int ultima_riga_buona = -1; - - for (k = 0; k < pn.iva_items() && !residuo.is_zero(); k++) - { - TRectype& iva_k = pn.iva(k); - const TBill conto_k(iva_k); - - if (conto_k == zio) - { - const real imposta_k = iva_k.get_real(RMI_IMPOSTA); - if (residuo >= imposta_k) - { - residuo -= imposta_k; - iva_k.zero(RMI_IMPOSTA); - } - else - { - iva_k.put(RMI_IMPOSTA, imposta_k - residuo); - residuo = ZERO; - } - ultima_riga_buona = k; - } - } - //alla fine del ciclo sull'array resta un residuo non nullo.. - if (!residuo.is_zero()) - { - if (ultima_riga_buona >= 0) - { - TRectype& iva_k = pn.iva(k); - iva_k.put(RMI_IMPOSTA, -residuo); - } - } - return true; -} - -void TInvioP::stringa_grcosot(TRecord_text& recrighe, const TString& zio) -{ - TString8 grcosot; - long gcs = 0; - - gcs = atoi(zio.left(3)); - grcosot.format("%d", gcs); - recrighe.add(grcosot, 3); //gruppo - - gcs = atoi(zio.mid(3,3)); - grcosot.format("%d", gcs); - recrighe.add(grcosot, 4); //conto - - gcs = atoi(zio.mid(6,6)); - grcosot.format("%d", gcs); - recrighe.add(grcosot, 5); //sottoconto -} - -// Calcola il totale del documento tenendo conto del segno della prima riga e di quella delle -// ritenute sociali sulla causale -real TInvioP::totale_documento(TMovimentoPN& pn, const bool includi_ritenute) const -{ - //testata del movimento di prima nota - const TRectype& mov = pn.curr(); - - real tot = mov.get_real(MOV_TOTDOC); // Legge totale - //i conti sulle ritenute li deve fare solo se il movimento e' iva!! - if (pn.iva_items() > 0) - { - if (includi_ritenute) - { - const real ritfis = mov.get_real(MOV_RITFIS); - tot += ritfis; // Somma ritenute fiscali - - const real ritsoc = mov.get_real(MOV_RITSOC); - - if (!ritsoc.is_zero()) - { - TCausale caus(mov.get(MOV_CODCAUS)); - const bool swapt = test_swap(caus, false); // Totale invertito ? - const bool swaps = test_swap(caus, true); // Ritenute sociali invertite ? - if (swapt ^ swaps) // Somma ritenute sociali con segno - tot -= ritsoc; - else - tot += ritsoc; - } - } - } - else //movimenti non iva; calcolo delle ritenute - { - TCausale caus(mov.get(MOV_CODCAUS)); - const char sez = caus.sezione_clifo(); - bool tot_is_zero = tot.is_zero(); - TImporto totdoc(sez, tot); - for (int i = 0; i < pn.cg_items(); i++) - { - const TRectype& rmov = pn.cg(i); - const TBill conto(rmov); - const TImporto importo(rmov.get_char(RMV_SEZIONE), rmov.get_real(RMV_IMPORTO)); - - if (tot_is_zero && rmov.get_char(RMV_TIPOC) > ' ') - totdoc += importo; - else - { - if (includi_ritenute && (cerca_fiscali(conto) || cerca_sociali(conto))) - totdoc += importo; //valore da stampare nella colonna Tot.fattura con ritenute - } - } - tot = totdoc.valore(); - } - return tot; -} - -// Controlla sulla causale se il segno del totale documento (ritsoc=FALSE) -// o quello delle ritenute sociali (ritsoc=TRUE) e' invertito rispetto al normale -bool TInvioP::test_swap(TCausale& caus, bool ritsoc) const -{ - const char sez = ritsoc ? caus.sezione_ritsoc() : caus.sezione_clifo(); - const bool s = (caus.iva() == iva_vendite) ^ (sez == 'D'); - return s; -} - -bool TInvioP::cerca_conto(const TBill& bill, const TAssoc_array& assoc, const char tipoconto) const -{ - TToken_string key(15); - key.add(tipoconto); //il primo char della tokenstring e' il tipoconto (Fiscale o Sociale) - - key.add(bill.gruppo()); - if (assoc.is_key(key)) - return true; - - key.add(bill.conto()); - if (assoc.is_key(key)) - return true; - - key.add(bill.sottoconto()); - if (assoc.is_key(key)) - return true; - - return false; -} - -int TInvioP::cerca_costo(const TBill& bill) const -{ - if (cerca_conto(bill, _costi, 'C')) - return 1; - else - return 0; -} - -int TInvioP::cerca_pagamento(const TBill& bill) const -{ - if (cerca_conto(bill, _pagamenti, 'P')) - return 2; - else - return 0; -} - -bool TInvioP::cerca_fiscali(const TBill& bill) const -{ - if (bill.tipo() > ' ') //non si vogliono i conti tipo Cliente Fornitore - return false; - - return cerca_conto(bill, _fiscali, 'F'); -} - -bool TInvioP::cerca_sociali(const TBill& bill) const -{ - if (bill.tipo() > ' ') //non si vogliono i conti tipo Cliente Fornitore - return false; - - return cerca_conto(bill, _sociali, 'S'); -} - -void TInvioP::lettura_conti(TAssoc_array& assoc, const char tipoconto) -{ - TConfig conti("ca3600a.ini","Pdcc"); //paragrafo da scandire nell'ini - TAssoc_array& vars = conti.list_variables(); - - FOR_EACH_ASSOC_STRING(vars, h, k, val) //riempie l'assoc con i soli valori del paragrafo dell'ini - { - if (*val == tipoconto) //mette nell'assocarray solo i conti corrispondenti al tipoconto passato - assoc.add(val); - } -} - -void TInvioP::calcola_imposte(const real& importo, const real& imposta, - const TString& codind, real& iva_det, real& iva_ind) const -{ - iva_det = imposta; - iva_ind = ZERO; - - //esiste un codice di indetraibilita'? - if (codind.full()) - { - real perc = ZERO; - const TRectype& rec = cache().get("%DET", codind); - if (rec.empty()) - { - if (strchr("139", codind[0]) != NULL) // Clausola di salvaguardia - perc = CENTO; - } - else - { - if (rec.get_int("I0") > 0) - perc = rec.get_real("R0"); - } - //valori delle varie ive - iva_ind = imposta * perc / CENTO; - iva_ind.round(2); - iva_det = imposta - iva_ind; - } -} - -bool TInvioP::calcola_imponibile_totdoc(const long nreg, const TRectype& pag_rec, real& imponibile, real& totdoc, real& totpagato, real& iva_indetraibile) const -{ - totpagato = pag_rec.get_real(PAGSCA_IMPORTO); - - TMovimentoPN pn; - pn.curr().put(MOV_NUMREG, nreg); - bool ok = nreg > 0 && pn.read() == NOERR; - if (ok) - { - //percentuale di pagamento sul totale documento senza ritenute - const real totdoc_no_rit = totale_documento(pn, false); - const real perc_ritenute = totpagato / totdoc_no_rit; - //Movimenti CON SALDACONTO - //se movimento IVA.. - if (pn.iva_items() > 0) - { - real imposta; - const TRectype& movfat = pn.curr(); - - real ritfis = movfat.get_real(MOV_RITFIS); //ritenute sulla fattura: verranno pagate percentualmente - if (perc_ritenute < UNO) - { - ritfis *= perc_ritenute; - ritfis.round(2); - } - totpagato += pag_rec.get_real(PAGSCA_RITENUTE); //ritenute eventuali sul pagamento - totpagato += ritfis; - - //Le ritenute sociali invece vanno testate con la test_swap.. - real ritsoc = movfat.get_real(MOV_RITSOC); - if (perc_ritenute < UNO) - { - ritsoc *= perc_ritenute; - ritsoc.round(2); - } - ritsoc += pag_rec.get_real(PAGSCA_RITSOC); - - if (!ritsoc.is_zero()) - { - const TRectype& mov = pn.curr(); - TCausale caus(mov.get(MOV_CODCAUS)); - const bool swapt = test_swap(caus, false); // Totale invertito ? - const bool swaps = test_swap(caus, true); // Ritenute sociali invertite ? - if (swapt ^ swaps) // Somma ritenute sociali con segno - totpagato -= ritsoc; - else - totpagato += ritsoc; - } - for (int i = 0; i < pn.iva_items(); i++) - { - const TRectype& rmoviva = pn.iva(i); - const TBill conto(rmoviva); - - if (conto.indicatore_bilancio() != 5) - { - const real importo = rmoviva.get_real(RMI_IMPONIBILE); - const real iva = rmoviva.get_real(RMI_IMPOSTA); - //trattamento delle ive indetraibili! - const TString& codind = rmoviva.get(RMI_TIPODET); - - imponibile += importo; - - real iva_det, iva_ind; - //calcola i valori dell'iva detraibile e delle ive indetraibili in diverse percentuali - calcola_imposte(importo, iva, codind, iva_det, iva_ind); - //se esiste un'iva indetraibile.. - if (iva_ind != ZERO) - { - iva_indetraibile += iva_ind; - imponibile += iva_ind; - } - //l'iva detraibile va sempre bene sommata alle imposte - imposta += iva_det; - } - } - totdoc = totale_documento(pn); //tot doc con ritenute fiscali + ritenute sociali - - } //if pn.iva_items().. - else //NON iva - { - totdoc = totale_documento(pn); //tot doc con ritenute fiscali + ritenute sociali - imponibile = totdoc; //nel caso di non iva - - TCausale caus(pn.curr().get(MOV_CODCAUS)); - TImporto totpag(caus.sezione_clifo(), totpagato); - for (int i = 0; i < pn.cg_items(); i++) - { - const TRectype& rmov = pn.cg(i); - const TBill conto(rmov); - if (cerca_fiscali(conto) || cerca_sociali(conto)) - { - real imp = rmov.get_real(RMV_IMPORTO); - if (perc_ritenute < UNO) - { - imp *= perc_ritenute; - imp.round(2); - } - const TImporto importo(rmov.get_char(RMV_SEZIONE), imp); - totpag += importo; //valore da stampare nella colonna Tot.fattura con ritenute - } - } - totpagato = totpag.valore(); - } - } //if (pn.read() == NOERR - return ok; -} - -real TInvioP::calcola_pagamento(TRectype& curpag_rec, real& iva_indetraibile) -{ - //deve costruirsi la riga di partita che riguarda il documento di origine - //per prima cosa crea tale riga a partire dal pagamento, che ha una chiave lunghissima... - TToken_string key_part; - key_part.add(curpag_rec.get(PAGSCA_TIPOC)); - key_part.add(curpag_rec.get(PAGSCA_GRUPPO)); - key_part.add(curpag_rec.get(PAGSCA_CONTO)); - key_part.add(curpag_rec.get(PAGSCA_SOTTOCONTO)); - key_part.add(curpag_rec.get(PAGSCA_ANNO)); - key_part.add(curpag_rec.get(PAGSCA_NUMPART)); - key_part.add(curpag_rec.get(PAGSCA_NRIGA)); - //..ecco il record delle partite.. - const TRectype& rec_partite = cache().get(LF_PARTITE, key_part); - //..da cui prende nreg - const long nreg = rec_partite.get_long(PART_NREG); - //se nreg esiste... - - //dichiariamo una serie di simpatici real utilizzati in seguito - real totdoc,imponibile,totpagato; - - if (calcola_imponibile_totdoc(nreg, curpag_rec, imponibile, totdoc, totpagato, iva_indetraibile)) - { - const real percentuale = totpagato /totdoc; - //cerca se esiste una fattura da ricevere anteriore alla fattura da pagare - const long fdr = calcola_fattura_originale(nreg); - //se la trova deve tenerne conto in quanto la presente fattura (nreg) potrebbe pagare solo.. - //..una parte della fdr originale - if (fdr != nreg) - { - real imponibile_fdr, totdoc_fdr, totpagato_fdr, iva_indetraibile_fdr; - //riutilizza la calcola_imponibile_totdoc per l'fdr;si fa notare che in questo caso gli.. - //..ultimi due parametri del metodo sono del tutto inutili - if (calcola_imponibile_totdoc(fdr, curpag_rec, imponibile_fdr, totdoc_fdr, totpagato_fdr, iva_indetraibile_fdr)) - { - const real rapporto_pagati = totdoc / totdoc_fdr; - const real rapporto_imponibili = imponibile_fdr / imponibile; - //la fattura con totdoc paga una parte di una precedente fdr con totdoc maggiore! - //in questo caso totpagato e' quello della fattura e deve uscire senza ricalcolare.. - //..percentuali e cazzi vari (funziona ststisticamente!) - if (rapporto_pagati >= 0.7) - imponibile = imponibile_fdr; - - if (rapporto_imponibili < 0.7 || rapporto_imponibili > 0.85) - iva_indetraibile = ZERO; - } - } //if(fdr!=nreg.. - else //se non esiste una fdr eventuali ive indetraibili non sussistono - iva_indetraibile = ZERO; - - //calcolo finale del pagato - totpagato = imponibile * percentuale; - totpagato.round(2); - - } //if(calcola_imponibile_totdoc(nreg,... - - return totpagato; -} - -long TInvioP::calcola_fattura_originale(long nreg) const -{ - //prende il movimento del pagamento - const TRectype& mov = cache().get(LF_MOV, nreg); - - TToken_string key; - key.add(mov.get(MOV_DCODNUM)); - key.add(mov.get(MOV_DANNO)); - key.add(mov.get(MOV_DPROVV)); - key.add(mov.get(MOV_DNDOC)); - //crea il documento da cui deriva tale movimento (per il CSA e' in genere una fattura) - - TRecord_array doc(key, LF_RIGHEDOC); - for (int i = 1; i <= doc.rows(); i++) - { - const TRectype& rdoc = doc.row(i); - const TString& dacodnum = rdoc.get(RDOC_DACODNUM); - if (dacodnum.full()) - { - const TRectype& num_rec = cache().get("%NUM", dacodnum); - if (num_rec.get_bool("B3")) - { - key = rdoc.get(RDOC_DAPROVV); - key.add(rdoc.get(RDOC_DAANNO)); - key.add(dacodnum); - key.add(rdoc.get(RDOC_DANDOC)); - //cerca da quale documento deriva la fattura (la prima riga che trova e' ok) - const TRectype& original_doc = cache().get(LF_DOC, key); - //se trova il documento origine (per il CSA e' in genere una FDR) -> prende il suo nreg.. - //..come nreg da ritornare (attenzione che se il doc originale non e' stato contabilizzato.. - //..nreg diventa 0!) - if (!original_doc.empty()) - { - nreg = original_doc.get_long(DOC_NUMREG); - } - } - break; - } - } - return nreg; -} - -// oggetto che serve per memorizzare importo e flag acc/sal dei pagamenti.. -//..(usato nel trasferimento pagamenti) -struct TPay_info : public TObject -{ - real _somma; - char _as; -}; - -bool TInvioP::i_proforma_pagamenti() -{ - TInvioP_file* trasfilepag = apri_file("pagament"); - - TRectype da(LF_MOV); - TRectype a(LF_MOV); - da.put(MOV_DATAREG, _dataini); - a.put(MOV_DATAREG, _datafin); - TRelation rel(LF_MOV); - rel.add(LF_CAUSALI, "CODCAUS==CODCAUS"); - TCursor cur(&rel, "", 2, &da, &a); - const long cur_items = cur.items(); - - if (cur_items != 0) - { - //se ha almeno un movimento carica lo sheet dei conti che gli servira' in seguito nel calcolo.. - //..delle ritenute - lettura_conti(_fiscali, 'F'); - lettura_conti(_sociali, 'S'); - lettura_conti(_costi, 'C'); - lettura_conti(_pagamenti, 'P'); - - TProgind pi(cur_items, "Trasferimento pagamenti...", true, true); - - cur.freeze(); - TRectype& cur_rec = cur.curr(); - for (cur = 0; cur.pos() < cur_items; ++(cur)) - { - if (!pi.addstatus(1)) - break; - - //pagamenti saldacontati! vedi l'else per quelli non saldacontati - const tipo_movimento tipomov = (tipo_movimento)cur_rec.get_int(MOV_TIPOMOV); - if (tipomov == tm_pagamento || tipomov == tm_nota_credito || tipomov == tm_pagamento_insoluto) - { - //attraverso le partite,noto il MOV_NUMREG,riesce a collegarsi al pagamento in LF_PAGSCA - TRelation relpart(LF_PARTITE); - TRectype da(LF_PARTITE); - da.put(PART_NREG, cur_rec.get(MOV_NUMREG)); - TCursor curpart(&relpart, "", 2, &da, &da); - const long curpart_items = curpart.items(); - //se trova la partita relativa al numreg... - if (curpart_items != 0) - { - curpart.freeze(); - TRectype& curpart_rec = curpart.curr(); - TRelation relpag(LF_PAGSCA); - TRectype da(LF_PAGSCA); - //..collega i pagamenti filtrando con i parametri estratti dalle partite - for (curpart = 0; curpart.pos() < curpart_items; ++(curpart)) - { - da.put(PAGSCA_TIPOC, curpart_rec.get(PART_TIPOCF)); - da.put(PAGSCA_GRUPPO, curpart_rec.get(PART_GRUPPO)); - da.put(PAGSCA_CONTO, curpart_rec.get(PART_CONTO)); - da.put(PAGSCA_SOTTOCONTO, curpart_rec.get(PART_SOTTOCONTO)); - da.put(PAGSCA_ANNO, curpart_rec.get(PART_ANNO)); - da.put(PAGSCA_NUMPART, curpart_rec.get(PART_NUMPART)); - const int nrigapart = curpart_rec.get_int(PART_NRIGA); - TString80 filtro; - filtro.format("NRIGP == %d", nrigapart); - TCursor curpag(&relpag, filtro, 1, &da, &da); - const long curpag_items = curpag.items(); - - real iva_indet = ZERO; //valore dell'eventuale iva indetraibile - - //se trova i pagamenti,che sono alla fin fine cio' che cerca... - if (curpag_items != 0) - { - TAssoc_array pagame; - pagame.destroy(); - curpag.freeze(); - TRectype& curpag_rec = curpag.curr(); - for (curpag = 0; curpag.pos() < curpag_items; ++(curpag)) - { - TString80 indice = curpag_rec.get(PAGSCA_ANNO); - indice << '|' << curpag_rec.get(PAGSCA_NUMPART); - indice << '|' << curpag_rec.get(PAGSCA_NRIGA); - - TPay_info* pi = (TPay_info*)pagame.objptr(indice); - if (pi == NULL) - { - pi = new TPay_info; - pi->_as = 'A'; - pagame.add(indice, pi); - } - - //ricava l'importo del pagamento e lo aggiunge al memorizzatore - const real importo_pagato = calcola_pagamento(curpag_rec, iva_indet); - pi->_somma += importo_pagato; - if (curpag_rec.get_char(PAGSCA_ACCSAL) == 'S') - pi->_as = 'S'; - } - - // scrive i record risultanti - for (TPay_info* pi = (TPay_info*)pagame.first_item(); pi != NULL; pi = (TPay_info*)pagame.succ_item()) - { - TToken_string keypart; - keypart.add(curpart_rec.get(PART_TIPOCF)); - keypart.add(curpart_rec.get(PART_GRUPPO)); - keypart.add(curpart_rec.get(PART_CONTO)); - keypart.add(curpart_rec.get(PART_SOTTOCONTO)); - keypart.add(pagame.get_hashobj()->key()); - const TRectype& fattura = cache().get(LF_PARTITE, keypart); - _nregpag = cur_rec.get_long(MOV_NUMREG); //registrazione del movimento di pagamento - //deve cercare la prima registrazione da cui deriva il pagamento.. - const long nregfatt = fattura.get_long(PART_NREG); - _nregcosto = calcola_fattura_originale(nregfatt); - _importo = pi->_somma; - //acconto/saldo in modo standard - _accsal = pi->_as; - //Casino plutonico dell'acconto-saldo in ottica CSA - //Se il doc in esame discende da una FDR (fattura da ricevere) e' necessario.. - //..cercare tutte le righe dei documenti che pagano tale FDR e sommare gli importi di tali.. - //..rdocs con quello corrente; solo se tale somma risulatsse >= del totale delle righe.. - //..della FDR originale il flag _accsal deve essere messo a saldo 'S' - if (_nregcosto != nregfatt) - { - //deve risalire al documento FDR del movimento _nregcosto - const TRectype& mov_fdr = cache().get(LF_MOV, _nregcosto); - - const TString8 fdr_codnum = mov_fdr.get(MOV_DCODNUM); - const int fdr_anno = mov_fdr.get_int(MOV_DANNO); - const char fdr_provv = mov_fdr.get_char(MOV_DPROVV); - const long fdr_ndoc = mov_fdr.get_long(MOV_DNDOC); - - //adesso che ha la chiave del documento padre FDR, deve crearsi la query.. - //..su RDOC alla ricerca di tutte le righe doc che discendono dall'FDR.. - //..In pratica cerca le "sorelle" dell'attuale fattura nregfatt - TString query; - query << "USE RDOC KEY 4"; - query << "\nFROM DACODNUM=" << fdr_codnum << " DAANNO=" << fdr_anno << " DAPROVV=" << fdr_provv << " DANDOC=" << fdr_ndoc; - query << "\nTO DACODNUM=" << fdr_codnum << " DAANNO=" << fdr_anno << " DAPROVV=" << fdr_provv << " DANDOC=" << fdr_ndoc; - - TISAM_recordset recset(query); - const int righe_delle_sorelle = recset.items(); - TAssoc_array sorelle; - TToken_string key; - //cerco la mia data di fattura; - const TDate datadoc_fattura = cache().get(LF_MOV, nregfatt, MOV_DATAREG); - //dalle righe risale ai documenti di tali righe (che posssono essere meno) - for (bool ok = recset.move_first(); ok; ok = recset.move_next()) - { - key = recset.get(RDOC_PROVV).as_string(); - key.add(recset.get(RDOC_ANNO).as_string()); - key.add(recset.get(RDOC_CODNUM).as_string()); - key.add(recset.get(RDOC_NDOC).as_string()); - - const TDate datadoc = cache().get(LF_DOC, key, DOC_DATADOC); - //se non sono l'ultima fattura (sorella piu' giovane) allora e'.. - //..sicuramente Acconto! Quindi esce dai cicli for e if - if (datadoc > datadoc_fattura) - { - sorelle.destroy(); - _accsal = 'A'; - break; - } - //accresce l'array delle sorelle - sorelle.add(key, key); - } - //tutto il casino s'ha da fare solo in caso ci sia piu' di una fattura.. - //.."sorella" di quella in esame - if (sorelle.items() > 1) - { - real importo_totale_sorelle; - //giro su tutti i documenti delle sorelle - FOR_EACH_ASSOC_OBJECT(sorelle, obj, chiave, itm) - { - TToken_string& ts = *(TToken_string*)itm; - TDocumento sorella(ts.get_char(0), ts.get_int(1), ts.get(2), ts.get_long(3)); - //per ogni documento deve cercare le righe discendenti dall'FDR - for (int r = 1; r <= sorella.rows(); r++) - { - const TRiga_documento nipotina = sorella[r]; - //servono solo le righe discendenti dall'FDR madre! - if (nipotina.get(RDOC_DACODNUM) == fdr_codnum && nipotina.get_int(RDOC_DAANNO) == fdr_anno && - nipotina.get_char(RDOC_DAPROVV) == fdr_provv && nipotina.get_long(RDOC_DANDOC) == fdr_ndoc) - { - const real importo_da_aggiungere = nipotina.importo(true, false); //importo scontato netto - importo_totale_sorelle += importo_da_aggiungere; - } - } - } //FOR_EACH_ASSOC.. - - //Se arriva fin qui la fattura in esame e' la sorella piu' giovane; adesso.. - //..deve controllare se gli importi di tutte le sorelle sommati saldano.. - //..o meno l'importo dell'originale mamma FDR... - - //intanto ha bisogno del totale documento FDR originale a partire dal movimento FDR... - real totale_fdr = ZERO; - TMovimentoPN movimento_fdr; - movimento_fdr.curr().put(MOV_NUMREG, _nregcosto); - if (movimento_fdr.read() == NOERR) - totale_fdr = totale_documento(movimento_fdr, false); //non include ritenute - - real rimanenza = totale_fdr - importo_totale_sorelle; - //arrotonda - rimanenza.round(); - - //Se l'importo e' inferiore la FDR non e' ancora stata saldata (nasceranno.. - //..una o piu' sorelle per saldare mamma FDR in futuro) - if (rimanenza > ZERO) - _accsal = 'A'; - //Se l'importo e' >= -> la mamma e' saldata e non sono previste ulteriori.. - //..sorelle (per la felicita' del papa'!) - else - _accsal = 'S'; - - } //if(sorelle.items()>1.. - - } //if(_nregcosto!=nregfatt.. - //..e finalmente scrive 'sta minchia di riga - TRecord_text recpag; - recpag.set_type("G"); - trasfilepag->autoload(recpag, curpag); - trasfilepag->write(recpag); - - //se ha una riga di iva indetraibile dovuta al cambio regime fiscale 2005->2006.. - //..deve aggiungere una ulteriore riga!! - if (iva_indet > ZERO) - { - _nregcosto = nregfatt; - _importo = iva_indet; - _accsal = 'S'; - recpag.set_type("G"); - trasfilepag->autoload(recpag, curpag); - trasfilepag->write(recpag); - } - } //for( - - }//if curpag_items.. - }//for curpart =.. - }//if curpart_items.. - - }//if tipomov ==.. - if (tipomov == tm_nessuno) //tocca ai pagamenti NON saldacontati (procedura analoga a quella della stampa del pagato) - { - const long numregcg = cur_rec.get_long(MOV_NUMREG); - - //cerca un record di MOVANA che abbia numregcg = nreg;usa il nuovo metodo fighissimo.. - //..con la isam query - TString& query = get_tmp_string(); - query << "USE MOVANA KEY 3\n"; - query << "FROM NUMREGCG=" << numregcg << "\n"; - query << "TO NUMREGCG=" << numregcg; - - TISAM_recordset movana(query); - const TRecnotype items = movana.items(); - - if (items > 0) - { - if (items > 1) - error_box(TR("Esiste piu' di un movimento analitico collegato al movimento contabile %ld"),numregcg); - - movana.move_last(); //si posiziona sul record corretto - - //crea il movana legato al mov - const TAnal_mov anal_mov(cur_rec); - const TRecord_array& anal_rows = anal_mov.body(); - - for (int j = 1; j <= anal_rows.rows(); j++) //scansiona righe analitiche.. - { - const TRectype& anal_row = anal_rows[j]; - - //prende il conto sulla riga analitica e lo confronta con quelli della configurazione - const TString& conto_riga_analitica = anal_row.get(RMOVANA_CODCONTO); - const int gruppo_anal = atoi(conto_riga_analitica.left(3)); - const int conto_anal = atoi(conto_riga_analitica.mid(3,3)); - const long sottoconto_anal = atol(conto_riga_analitica.mid(6,6)); - - const TBill conto(gruppo_anal, conto_anal, sottoconto_anal); - int tipo = cerca_costo(conto) || cerca_pagamento(conto); - if (tipo > 0) - { - const char sezione = anal_row.get_char(RMOVANA_SEZIONE); - const real valore = anal_row.get_real(RMOVANA_IMPORTO); - TImporto imp(sezione, valore); - - switch (tipo) - { - case 1:imp.normalize('D');break; - case 2:imp.normalize('A');break; - default:break; - } - _nregpag = numregcg; - _nregcosto = numregcg; - _importo = imp.valore(); - //deve stabilire adesso se acconto o saldo controllando gli importi - _accsal = 'S'; - - //e finalmente aggiunge il record al file di esportazione - TRecord_text recpag; - recpag.set_type("G"); - trasfilepag->autoload(recpag, *movana.cursor()); - trasfilepag->write(recpag); - } //if (tipo > 0.. - - } //for(j0... - - } //else if tipomov ==.. - - }//for cur =.. - }//if cur_items.. - - chiudi_file(trasfilepag); - return true; -} - -bool TInvioP::i_proforma_clifor(char tipocf) -{ - TInvioP_file* trasfile = NULL; - - TString progind_string = "Trasferimento "; - - if (tipocf == 'C') - { - trasfile = apri_file("clienti"); - progind_string << "clienti"; - } - else - { - trasfile = apri_file("fornit"); - progind_string << "fornitori"; - } - - TString80 filtro = ""; - filtro.format("TIPOCF == \"%c\"", tipocf); - TRelation rel(LF_CLIFO); - rel.add(LF_COMUNI, "STATO==STATOCF|COM==COMCF", 1); - TCursor cur(&rel, filtro); - const long cur_items = cur.items(); - - if (cur_items != 0) - { - progind_string << "..."; - TProgind pi(cur_items, progind_string, true, true); - - cur.freeze(); - TRectype& cur_rec = cur.curr(); - for (cur = 0; cur.pos() < cur_items; ++(cur)) - { - pi.addstatus(1); - if (pi.iscancelled()) - break; - - TRecord_text rec; - rec.set_type("C"); - trasfile->autoload(rec, cur); - trasfile->write(rec); - } - } - chiudi_file(trasfile); - return true; -} - -//"metodo dei metodi":in base ai parametri della maschera esegue la procedura indicata -void TInvioP::invio_proforma() -{ - if (_msk->get_bool(F_MOVIMENTI)) - i_proforma_movimenti(); - if (_msk->get_bool(F_PAGAMENTI)) - i_proforma_pagamenti(); - if (_msk->get_bool(F_CLIENTI)) - i_proforma_clifor(); - if (_msk->get_bool(F_FORNITORI)) - i_proforma_clifor('F'); - if (_msk->get_bool(F_CONTI)) - i_proforma_conti(); -} - -bool TInvioP::create() -{ - _msk = new TInvioP_mask(); - _configfile = new TConfig("tc9100a.ini"); - return TSkeleton_application::create(); -} - -bool TInvioP::destroy() -{ - if (_configfile != NULL) - delete _configfile; - delete _msk; - - return TSkeleton_application::destroy(); -} - -void TInvioP::main_loop() -{ - //il programma si puo' usare SOLO se in contabilita' analitica si usa il piano dei conti contabile - TConfig& cfg = ca_config(); - const bool use_pdcc = cfg.get_bool("UsePdcc"); - if (!use_pdcc) - { - error_box(TR("Programma funzionante SOLO se in contabilita' analitica si usa il piano dei conti contabile")); - return; - } - - TFilename configname = "tc9100conf.ini"; //file configurazione della maschera - configname.custom_path(); - TConfig configfile(configname); - _msk->set(F_DATAINI, configfile.get("DATA","OPZIONI")); - _msk->set(F_DESTINAZIONE, configfile.get("PERCORSO","OPZIONI")); - - while (_msk->run()!=K_QUIT) - { - configfile.set("DATA", _msk->get_date(F_DATAFIN),"OPZIONI"); - configfile.set("PERCORSO", _msk->get(F_DESTINAZIONE),"OPZIONI"); - _dataini = _msk->get_date(F_DATAINI); - _datafin = _msk->get_date(F_DATAFIN); - const char tipoinvio = _msk->get(F_TIPOINVIO)[0]; - if (tipoinvio == 'P') - invio_proforma(); //dopo aver preso i parametri dalla maschera chiama il "metodo dei metodi" - } -} int tc9100(int argc, char **argv) { - TInvioP a; - a.run(argc, argv, "Invio dati contabilitą a Proforma"); - - return 0; + return 0; } diff --git a/tc/tc9100a.h b/tc/tc9100a.h index 4f35bf6a5..dbc9d777a 100755 --- a/tc/tc9100a.h +++ b/tc/tc9100a.h @@ -1,23 +1,15 @@ // invio dati ad altra procedura (Proforma) -#define F_CODDITTA 301 -#define F_RAGSOC 302 -#define F_MOVIMENTI 303 -#define F_CLIENTI 304 -#define F_FORNITORI 305 -#define F_CONTI 306 -#define F_PAGAMENTI 307 -#define F_TIPOINVIO 308 -#define F_DESTINAZIONE 309 -#define F_DATAINI 310 -#define F_DATAFIN 311 -#define F_RIPRISTINA 312 -#define F_DATARIPRISTINO 313 - -#define F_PDCC 315 - -#define S_TIPO 101 -#define S_GRUPPO 102 -#define S_CONTO 103 -#define S_SOTTOCONTO 104 -#define S_DESCRIZIONE 105 +#define F_CODDITTA 101 +#define F_RAGSOC 102 +#define F_MOVIMENTI 103 +#define F_CLIENTI 104 +#define F_FORNITORI 105 +#define F_CONTI 106 +#define F_PAGAMENTI 107 +#define F_TIPOINVIO 108 +#define F_DESTINAZIONE 109 +#define F_DATAINI 110 +#define F_DATAFIN 111 +#define F_RIPRISTINA 112 +#define F_DATARIPRISTINO 113 diff --git a/tc/tc9100a.ini b/tc/tc9100a.ini index 892943b26..0ed66a8db 100755 --- a/tc/tc9100a.ini +++ b/tc/tc9100a.ini @@ -7,426 +7,3 @@ SKIPLINES = 0 TYPEFIELD = -1 TYPELEN = -1 TYPEPOS = -1 - -[TYPE STRINGA] -ALIGN = L -DATA = S -DECIMAL = 0 -FILLER = ' ' -LENGTH = 0 -PICTURE = - -[TYPE NUMERO] -ALIGN = R -DATA = N -DECIMAL = 0 -FILLER = '0' -PICTURE = - -[TYPE DATA] -ALIGN = -DATA = D -DECIMAL = 0 -FILLER = '0' -LENGTH = 8 -PICTURE = 1444 - -[TYPE IMPORTO] -ALIGN = R -DATA = N -DECIMAL = 2 -FILLER = '0' -LENGTH = 14 -PICTURE = @@@@@@@@@,@@ - -[RECORD T] - -NAME(0) = ID REGISTRAZIONE -TYPE(0) = NUMERO -POSITION(0) = 0 -LENGTH(0) = 10 -FIELD(0) = NUMREG - -NAME(1) = DATA REGISTRAZIONE -TYPE(1) = DATA -POSITION(1) = 10 -LENGTH(1) = 8 -FIELD(1) = DATAREG - -NAME(2) = CODICE CAUSALE -TYPE(2) = STRINGA -POSITION(2) = 18 -LENGTH(2) = 3 -FIELD(2) = CODCAUS - -NAME(3) = DESCRIZIONE CAUSALE -TYPE(3) = STRINGA -POSITION(3) = 21 -LENGTH(3) = 40 -FIELD(3) = 26->DESCR[1,40] - -NAME(4) = DESCRIZIONE TESTATA -TYPE(4) = STRINGA -POSITION(4) = 61 -LENGTH(4) = 240 -FIELD(4) = DESCR[1,40] - -NAME(5) = DATA DOCUMENTO -TYPE(5) = DATA -POSITION(5) = 301 -LENGTH(5) = 8 -FIELD(5) = DATADOC - -NAME(6) = NUMERO DOCUMENTO -TYPE(6) = STRINGA -POSITION(6) = 309 -LENGTH(6) = 6 -FIELD(6) = NUMDOC - -NAME(7) = TIPO DOCUMENTO -TYPE(7) = STRINGA -POSITION(7) = 315 -LENGTH(7) = 30 - -NAME(8) = CODICE CLIFOR -TYPE(8) = STRINGA -POSITION(8) = 345 -LENGTH(8) = 10 -FIELD(8) = CODCF - -NAME(9) = TOTALE IMPONIBILE -TYPE(9) = IMPORTO -POSITION(9) = 355 - -NAME(10) = TOTALE IVA -TYPE(10) = IMPORTO -POSITION(10) = 369 - -NAME(11) = TOTALE DOCUMENTO -TYPE(11) = IMPORTO -POSITION(11) = 383 -FIELD(11) = TOTDOC - -NAME(12) = DATA PAGAMENTO -TYPE(12) = DATA -POSITION(12) = 397 -LENGTH(12) = 8 - -NAME(13) = TIPO PAGAMENTO -TYPE(13) = STRINGA -POSITION(13) = 405 -LENGTH(13) = 20 -FIELD(13) = CODPAG - -NAME(14) = DATA COMPETENZA -TYPE(14) = DATA -POSITION(14) = 425 -LENGTH(14) = 8 -FIELD(14) = DATACOMP - -NAME(15) = NUMERO PROTOCOLLO -TYPE(15) = STRINGA -POSITION(15) = 433 -LENGTH(15) = 10 -FIELD(15) = PROTIVA - -NAME(16) = VALUTA -TYPE(16) = STRINGA -POSITION(16) = 443 -LENGTH(16) = 1 -MESSAGE(16)=_FISSO,!1 - -[RECORD R] - -NAME(0) = ID REGISTRAZIONE -TYPE(0) = NUMERO -POSITION(0) = 0 -LENGTH(0) = 10 -FIELD(0) = 23->NUMREG - -NAME(1) = FLAG RIGA IVA -TYPE(1) = STRINGA -POSITION(1) = 10 -LENGTH(1) = 1 -MESSAGE(1) = _FISSO,!N - -NAME(2) = FLAG DARE/AVERE -TYPE(2) = STRINGA -POSITION(2) = 11 -LENGTH(2) = 1 -FIELD(2) = SEZIONE - -NAME(3) = CODICE MASTRO -TYPE(3) = STRINGA -POSITION(3) = 12 -LENGTH(3) = 5 - -NAME(4) = CODICE CONTO -TYPE(4) = STRINGA -POSITION(4) = 17 -LENGTH(4) = 5 - -NAME(5) = CODICE SOTTOCONTO -TYPE(5) = STRINGA -POSITION(5) = 22 -LENGTH(5) = 5 - -NAME(6) = FLAG CLIFOR -TYPE(6) = STRINGA -POSITION(6) = 27 -LENGTH(6) = 1 - -NAME(7) = CODICE CLIFOR -TYPE(7) = STRINGA -POSITION(7) = 28 -LENGTH(7) = 10 - -NAME(8) = DESCRIZIONE RIGA -TYPE(8) = STRINGA -POSITION(8) = 38 -LENGTH(8) = 40 -FIELD(8) = DESCR[1,40] - -NAME(9) = IMPORTO SOTTOCONTO -TYPE(9) = IMPORTO -POSITION(9) = 78 -FIELD(9) = IMPORTO - -NAME(10) = IMPONIBILE -TYPE(10) = IMPORTO -POSITION(10) = 92 - -NAME(11) = CODICE IVA -TYPE(11) = STRINGA -POSITION(11) = 106 -LENGTH(11) = 4 - -NAME(12) = CP INDED -TYPE(12) = STRINGA -POSITION(12) = 110 -LENGTH(12) = 15 - -NAME(13) = COMMESSA -TYPE(13) = STRINGA -POSITION(13) = 125 -LENGTH(13) = 20 -FIELD(13) = CODCMS - -NAME(14) = SOTTOPROGETTO -TYPE(14) = STRINGA -POSITION(14) = 145 -LENGTH(14) = 20 - -NAME(15) = EDIZIONE -TYPE(15) = STRINGA -POSITION(15) = 165 -LENGTH(15) = 20 - -NAME(16) = VOCE DI SPESA -TYPE(16) = STRINGA -POSITION(16) = 185 -LENGTH(16) = 10 - -[RECORD I] - -NAME(0) = ID REGISTRAZIONE -TYPE(0) = NUMERO -POSITION(0) = 0 -LENGTH(0) = 10 -FIELD(0) = NUMREG - -NAME(1) = FLAG RIGA IVA -TYPE(1) = STRINGA -POSITION(1) = 10 -LENGTH(1) = 1 -MESSAGE(1) = _FISSO,!S - -NAME(3) = CODICE MASTRO -TYPE(3) = STRINGA -POSITION(3) = 12 -LENGTH(3) = 5 -FIELD(3) = GRUPPO - -NAME(4) = CODICE CONTO -TYPE(4) = STRINGA -POSITION(4) = 17 -LENGTH(4) = 5 -FIELD(4) = CONTO - -NAME(5) = CODICE SOTTOCONTO -TYPE(5) = STRINGA -POSITION(5) = 22 -LENGTH(5) = 5 -FIELD(5) = SOTTOCONTO - -NAME(6) = FLAG CLIFOR -TYPE(6) = STRINGA -POSITION(6) = 27 -LENGTH(6) = 1 -FIELD(6) = TIPOC - -NAME(7) = CODICE CLIFOR -TYPE(7) = STRINGA -POSITION(7) = 28 -LENGTH(7) = 10 - -NAME(8) = DESCRIZIONE RIGA -TYPE(8) = STRINGA -POSITION(8) = 38 -LENGTH(8) = 40 - -NAME(9) = IMPORTO SOTTOCONTO -TYPE(9) = IMPORTO -POSITION(9) = 78 - -NAME(10) = IMPONIBILE -TYPE(10) = IMPORTO -POSITION(10) = 92 -FIELD(10) = IMPONIBILE - -NAME(11) = CODICE IVA -TYPE(11) = STRINGA -POSITION(11) = 106 -LENGTH(11) = 4 -FIELD(11) = CODIVA - -NAME(12) = CP INDED -TYPE(12) = STRINGA -POSITION(12) = 110 -LENGTH(12) = 15 - -NAME(13) = COMMESSA -TYPE(13) = STRINGA -POSITION(13) = 125 -LENGTH(13) = 20 - -NAME(14) = SOTTOPROGETTO -TYPE(14) = STRINGA -POSITION(14) = 145 -LENGTH(14) = 20 - -NAME(15) = EDIZIONE -TYPE(15) = STRINGA -POSITION(15) = 165 -LENGTH(15) = 20 - -NAME(16) = VOCE DI SPESA -TYPE(16) = STRINGA -POSITION(16) = 185 -LENGTH(16) = 10 - - -[RECORD C] - -NAME(0) = CODICE -TYPE(0) = STRINGA -POSITION(0) = 0 -LENGTH(0) = 10 -FIELD(0) = 20->CODCF - -NAME(1) = RAGIONE SOCIALE -TYPE(1) = STRINGA -POSITION(1) = 11 -LENGTH(1) = 40 -MESSAGE(1) = _RAGSOC -FIELD(1) = 20->RAGSOC - -NAME(2) = PARTITA IVA -TYPE(2) = STRINGA -POSITION(2) = 50 -LENGTH(2) = 12 -FIELD(2)=20->PAIV - -NAME(3) = CODICE FISCALE -TYPE(3) = STRINGA -POSITION(3) = 62 -LENGTH(3) = 16 -FIELD(3) = 20->COFI - -NAME(4) = INDIRIZZO -TYPE(4) = STRINGA -POSITION(4) = 78 -LENGTH(4) = 40 -FIELD(4) = 20->INDCF - -NAME(5) = CAP DI RESIDENZA -TYPE(5) = STRINGA -POSITION(5) = 118 -LENGTH(5) = 5 -FIELD(5)=20->CAPCF - -NAME(6) = COMUNE DI RESIDENZA -TYPE(6) = STRINGA -POSITION(6) = 123 -LENGTH(6) = 23 -FIELD(6) = 13->DENCOM[1,40] - -NAME(7) = PROVINCIA DI RESIDENZA -TYPE(7) = STRINGA -POSITION(7) = 163 -LENGTH(7) = 2 -FIELD(7) = 13->PROVCOM - -NAME(8) = TELEFONO -TYPE(8) = STRINGA -POSITION(8) = 165 -LENGTH(8) = 20 -FIELD(8) = 20->TEL -MESSAGE(8) = _TELEFONO - -[RECORD P] - -NAME(0) = CODICE MASTRO -TYPE(0) = STRINGA -POSITION(0) = 0 -LENGTH(0) = 5 -FIELD(0)=19->GRUPPO - -NAME(1) = CODICE CONTO -TYPE(1) = STRINGA -POSITION(1) = 5 -B LENGTH(1) = 5 -FIELD(1)=19->CONTO - -NAME(2) = CODICE SOTTOCONTO -TYPE(2) = STRINGA -POSITION(2) = 10 -LENGTH(2) = 5 -FIELD(2)=19->SOTTOCONTO - -NAME(3) = DESCRIZIONE -TYPE(3) = STRINGA -POSITION(3) = 15 -LENGTH(3) = 80 -FIELD(3)=19->DESCR - -[RECORD G] - -NAME(0) = ID REGISTRAZIONE PAGAMENTO -TYPE(0) = NUMERO -POSITION(0) = 0 -LENGTH(0) = 10 -MESSAGE(0) = _NREGPAG - -NAME(1) = ID REGISTRAZIONE COSTO -TYPE(1) = NUMERO -POSITION(1) = 10 -LENGTH(1) = 10 -MESSAGE(1) = _NREGCOSTO - -NAME(2) = IMPORTO -TYPE(2) = IMPORTO -POSITION(2) = 20 -MESSAGE(2) = _IMPORTO - -NAME(3) = FLAG ACCONTO/SALDO -TYPE(3) = STRINGA -POSITION(3) = 34 -LENGTH(3) = 1 -MESSAGE(3) = _FLAG - -NAME(4) = VALUTA -TYPE(4) = STRINGA -POSITION(4) = 35 -LENGTH(4) = 1 -MESSAGE(4)=_FISSO,!1 diff --git a/tc/tc9100a.uml b/tc/tc9100a.uml index 4e0113027..0577d476f 100755 --- a/tc/tc9100a.uml +++ b/tc/tc9100a.uml @@ -1,19 +1,5 @@ #include "tc9100a.h" -TOOLBAR "" 0 -2 0 2 - -BUTTON DLG_OK 10 2 -BEGIN - PROMPT -12 -11 "" -END - -BUTTON DLG_QUIT 10 2 -BEGIN - PROMPT -22 -11 "" -END - -ENDPAGE - PAGE "Invio dati contabilita'" -1 -1 78 20 GROUPBOX DLG_NULL 76 3 @@ -45,188 +31,70 @@ END BOOLEAN F_MOVIMENTI BEGIN PROMPT 3 5 "Movimenti contabili" - MESSAGE FALSE CLEAR,F_PAGAMENTI|DISABLE,F_DATAFIN - MESSAGE TRUE ENABLE,F_PAGAMENTI|ENABLE,F_DATAFIN + MESSAGE TRUE,ENABLE F_DATAFIN END BOOLEAN F_CLIENTI BEGIN - PROMPT 3 6 "Clienti" + PROMPT 3 6 "Clienti" END BOOLEAN F_FORNITORI BEGIN - PROMPT 3 7 "Fornitori" + PROMPT 3 7 "Fornitori" END BOOLEAN F_CONTI BEGIN - PROMPT 3 8 "Piano dei conti" + PROMPT 3 8 "Piano dei conti" END BOOLEAN F_PAGAMENTI BEGIN - PROMPT 40 5 "Pagamenti" + PROMPT 40 5 "Pagamenti" END LISTBOX F_TIPOINVIO 20 BEGIN - PROMPT 2 10 "Invio a " - ITEM "P|Proforma" + PROMPT 2 10 "Invio a " + ITEM "P|Proforma" END STRING F_DESTINAZIONE 20 BEGIN - PROMPT 2 11 "Destinazione " + PROMPT 2 11 "Destinazione " END DATE F_DATAINI BEGIN - PROMPT 2 12 "Data iniziale " + PROMPT 2 12 "Data iniziale " END DATE F_DATAFIN BEGIN - PROMPT 40 12 "Data finale " + PROMPT 40 12 "Data finale " END -BUTTON F_RIPRISTINA 20 2 +BUTTON F_RIPRISTINA 20 BEGIN - PROMPT 2 14 "Annulla invio" - MESSAGE SHOW,F_DATARIPRISTINO|ENABLE,F_DATARIPRISTINO + PROMPT 2 14 "Annulla invio" + MESSAGE SHOW,F_DATARIPRISTINO|ENABLE,F_DATARIPRISTINO END DATE F_DATARIPRISTINO BEGIN - PROMPT 25 14 "Annulla invio fino al " - FLAGS "HD" + PROMPT 25 14 "Annulla invio fino al " + FLAGS "HD" END -ENDPAGE - -PAGE "Conti" -1 -1 78 20 - -TEXT -1 +BUTTON DLG_OK 9 2 BEGIN - PROMPT 1 1 "@bPiano dei conti contabile" + PROMPT -12 -1 "" END -SPREADSHEET F_PDCC 78 -6 +BUTTON DLG_QUIT 9 2 BEGIN - PROMPT 1 2 "Pdcc" - ITEM "Tipo" - ITEM "Gruppo" - ITEM "Conto" - ITEM "Sottoconto" - ITEM "Descrizione@50" -END - -TEXT -1 -BEGIN - PROMPT 1 17 "Inserire conti di tipo F per ritenute Fiscali" -END - -TEXT -1 -BEGIN - PROMPT 1 18 "S per ritenute Sociali, C per Costi, P per Pagamenti" -END - -BUTTON DLG_SAVEREC 12 2 -BEGIN - PROMPT -11 19 "" - PICTURE BMP_SAVEREC - PICTURE BMP_SAVERECDN -END - -ENDPAGE - -ENDMASK - -//-------------------------------------------------------------------- -// Riga dello sheet dei conti -//-------------------------------------------------------------------- - -PAGE "Riga Piano dei conti contabile" -1 -1 78 8 - -LIST S_TIPO 1 18 -BEGIN - PROMPT 1 1 "Tipo " - ITEM "C|Costi" - ITEM "P|Pagamenti" - ITEM "F|Ritenute fiscali" - ITEM "S|Ritenute sociali" -END - -NUMBER S_GRUPPO 3 -BEGIN - PROMPT 1 2 "Gruppo " - USE LF_PCON KEY 1 SELECT CONTO="" - INPUT GRUPPO S_GRUPPO - DISPLAY "Gruppo" GRUPPO - DISPLAY "Descrizione@50" DESCR - OUTPUT S_GRUPPO GRUPPO - CHECKTYPE REQUIRED -END - -NUMBER S_CONTO 3 -BEGIN - PROMPT 1 3 "Conto " - USE LF_PCON KEY 1 SELECT ((CONTO!="")&&(SOTTOCONTO="")) - COPY INPUT S_GRUPPO - INPUT CONTO S_CONTO - DISPLAY "Gruppo" GRUPPO - DISPLAY "Conto" CONTO - DISPLAY "Descrizione@50" DESCR - OUTPUT S_GRUPPO GRUPPO - OUTPUT S_CONTO CONTO - CHECKTYPE NORMAL - VALIDATE REQIF_FUNC 1 S_SOTTOCONTO -END - -NUMBER S_SOTTOCONTO 6 -BEGIN - PROMPT 1 4 "Sottoconto " - USE LF_PCON KEY 1 SELECT SOTTOCONTO!="" - COPY INPUT S_CONTO - INPUT SOTTOCONTO S_SOTTOCONTO - DISPLAY "Gruppo" GRUPPO - DISPLAY "Conto" CONTO - DISPLAY "Sottoconto" SOTTOCONTO - DISPLAY "Descrizione@50" DESCR - OUTPUT S_SOTTOCONTO SOTTOCONTO - OUTPUT S_CONTO CONTO - OUTPUT S_GRUPPO GRUPPO - OUTPUT S_DESCRIZIONE DESCR - CHECKTYPE NORMAL -END - -STRING S_DESCRIZIONE 50 -BEGIN - PROMPT 1 5 "Descrizione " - KEY 2 - USE LF_PCON KEY 2 - INPUT DESCR S_DESCRIZIONE - DISPLAY "Descrizione@50" DESCR - DISPLAY "Gruppo" GRUPPO - DISPLAY "Conto" CONTO - DISPLAY "Sottoconto" SOTTOCONTO - COPY OUTPUT S_SOTTOCONTO - CHECKTYPE REQUIRED -END - -BUTTON DLG_OK 10 2 -BEGIN - PROMPT -13 -1 "" -END - -BUTTON DLG_DELREC 10 2 -BEGIN - PROMPT -23 -1 "" -END - -BUTTON DLG_CANCEL 10 2 -BEGIN - PROMPT -33 -1 "" + PROMPT -22 -1 "" END ENDPAGE diff --git a/tc/tc9100conf.ini b/tc/tc9100conf.ini index a30989f60..139597f9c 100755 --- a/tc/tc9100conf.ini +++ b/tc/tc9100conf.ini @@ -1,5 +1,2 @@ -[OPZIONI] -CONFSTRINGA = -DATA = -PERCORSO = + diff --git a/tc/tc9200.cpp b/tc/tc9200.cpp index 13366dbf7..656cf5018 100755 --- a/tc/tc9200.cpp +++ b/tc/tc9200.cpp @@ -1,385 +1,7 @@ -#include -#include -#include - -#include "tc0.h" -#include "tc9200a.h" - -#include -#include -#include -#include - -#define ALIAS_REG 100 - -class TInvioS_file: public TFile_text -{ -protected: - virtual void validate(TCursor& cur,TRecord_text &rec, TToken_string &val, TString& str); - -public: - TInvioS_file(const TString& file_name); - virtual ~TInvioS_file() { } -}; - -TInvioS_file::TInvioS_file(const TString& file_name) - : TFile_text(file_name, "tc9200a.ini") -{ -} - -class TInvioS_mask : public TAutomask -{ -protected: - bool on_field_event(TOperable_field& o, TField_event e, long jolly); -public: - - TInvioS_mask(); - - virtual ~TInvioS_mask(){}; -}; - -TInvioS_mask::TInvioS_mask() :TAutomask ("tc9200a") -{ -} - -bool TInvioS_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) -{ - switch (o.dlg()) - { - case F_CODDITTA: - if (e==fe_init && o.empty()) - { - set(F_CODDITTA, main_app().get_firm()); - ((TEdit_field&) o).check(); - disable(F_CODDITTA); - } - break; - default: - break; - } - return TRUE; -} - -class TInvioS : public TSkeleton_application -{ - TCursor* _cur; - TInvioS_mask* _msk; - TInvioS_file* _trasfile; - TConfig* _configfile; - TDate _dataini, _datafin; - -protected: - virtual bool create(void); - virtual bool destroy(void); - virtual void main_loop() ; - void invio_sispac(); - long i_sispac_clifor(const char* tipocf, const bool invio = TRUE); - long i_sispac_movcont(const bool invio = TRUE); - long i_sispac_moviva(const bool invio = TRUE); - -public: - TInvioS_file* apri_file(const char* nome); - void chiudi_file(TInvioS_file* trasfile); - TConfig& config() {return *_configfile;}; - TInvioS() {} ; - virtual ~TInvioS() {} ; -}; - -// restituisce un riferimento all' applicazione -inline TInvioS& app() { return (TInvioS&) main_app();} - -// gestione dei messaggi estesi nei campi -void TInvioS_file::validate(TCursor& cur,TRecord_text &rec, TToken_string &s, TString& str) -{ - const TString code(s.get(0)); - TString valore; - if (code == "_FISSO") - { - // gestione dei campi fissi per i record delle riba - // sintassi: _FISSO,! - // dove: č la stringa fissa da emettere - TString in(s.get()); - CHECK(in[0]=='!',"Macro _FISSO senza carattere '!'"); - in.ltrim(1); - in.trim(); - valore = in; - } - else if (code == "_TIPORIGA") - { - valore = str.empty() ? " " : "S"; - } - else if (code == "_CODPAG") - { - valore = app().config().get(str, "PAGAMENTI"); - } - else if (code == "_OPZIONI") - { - TString in(s.get()); - valore = app().config().get(in, "OPZIONI"); - } - else if (code == "_IMPORTO") - { - real importo(str); - valore = importo.string(0,2); - valore.strip("-"); - valore.strip("+"); - valore.strip("."); - } - else if (code == "_IMPORTORIGAIVA") - { - real imponibile = cur.curr(LF_RMOVIVA).get_real(RMI_IMPONIBILE);; - real imposta = cur.curr(LF_RMOVIVA).get_real(RMI_IMPOSTA);; - imponibile += imposta; - valore = imposta.string(0,2); - valore.strip("-"); - valore.strip("+"); - valore.strip("."); - } - else if (code == "_INDIR") - { - valore = cur.curr(LF_CLIFO).get(CLI_INDCF); - valore << ' ' << cur.curr(LF_CLIFO).get(CLI_CIVCF); - valore.cut(40); - } - else if (code == "_GIUFIS") - { - const char c = str[0]; - valore = (c == 'F') ? "S" : "N"; - } - else if (code == "_TITOLARE") - { - valore = (str.empty() ? "N" : "S"); - } - else if (code == "_TIPODET") - { - valore = (str.empty() ? " " : "100"); - } - else if (code == "_CONTO") - { - int gruppo = cur.curr(LF_CLIFO).get_int(CLI_GRUPPO); - if (gruppo == 10) - gruppo = 0; - int conto = cur.curr(LF_CLIFO).get_int(CLI_CONTO); - long codice = cur.curr(LF_CLIFO).get_int(CLI_CODCF); - valore.format("%03d%03d%06ld", gruppo, conto, codice); - } - else if (code == "_CONTOMOV") - { - int gruppo = cur.curr(LF_RMOV).get_int(RMV_GRUPPO); - if (gruppo == 10) - gruppo = 0; - int conto = cur.curr(LF_RMOV).get_int(RMV_CONTO); - long codice = cur.curr(LF_RMOV).get_int(RMV_SOTTOCONTO); - valore.format("%03d%03d%06ld", gruppo, conto, codice); - } - else if (code == "_CONTOMOVIVA") - { - int gruppo = cur.curr(LF_RMOVIVA).get_int(RMI_GRUPPO); - if (gruppo == 10) - gruppo = 0; - int conto = cur.curr(LF_RMOVIVA).get_int(RMI_CONTO); - long codice = cur.curr(LF_RMOVIVA).get_int(RMI_SOTTOCONTO); - valore.format("%03d%03d%06ld", gruppo, conto, codice); - } - else NFCHECK("Macro non definita: %s", (const char *)code); - str = valore; -} - -TInvioS_file* TInvioS::apri_file(const char* nome) -{ - TFilename filename = _msk->get(F_DESTINAZIONE); - filename.add(nome); - filename.ext("txt"); - if (filename.exist()) - remove(filename); - TInvioS_file* trasfile = new TInvioS_file(filename); - trasfile->open(filename,'w'); - trasfile->force_record_separator(); - return trasfile; -} - -void TInvioS::chiudi_file(TInvioS_file* trasfile) -{ - trasfile->close(); - delete trasfile; -} - -long TInvioS::i_sispac_movcont(const bool invio) -{ - TRectype da(LF_MOV); - TRectype a(LF_MOV); - TDate dataini = _msk->get_date(F_DATAINI); - TDate datafin = _msk->get_date(F_DATAFIN); - if (dataini.ok()) - da.put(MOV_DATAREG, dataini); - if (datafin.ok()) - a.put(MOV_DATAREG, datafin); - TRelation rel(LF_MOV); - rel.add(LF_RMOV, "NUMREG==NUMREG", 1); - rel.add(LF_CLIFO, "TIPOCF==TIPO|CODCF==CODCF", 1); - TCursor cur(&rel, "", 2, &da, &a); - const long cur_items = cur.items(); - if (cur_items != 0) - { - cur.freeze(); - TRectype& cur_rec = cur.curr(); - for (cur = 0; cur.pos() < cur_items; ++(cur)) - { - const long numreg = cur.curr().get_long(MOV_NUMREG); - bool continua = TRUE; - while (continua) - { - const long numregrig = cur.curr(LF_RMOV).get_long(RMV_NUMREG); - if (numreg == numregrig) - { - if (invio) - { - TRectype& cur_rec_righe = cur.curr(LF_RMOV); - TRecord_text recrighe; - recrighe.set_type("R"); - _trasfile->autoload(recrighe, cur); - _trasfile->write(recrighe); - } - } - continua = cur.next_match(LF_RMOV, "NUMREG"); - } - } - } - return 0; -} - - -long TInvioS::i_sispac_moviva(const bool invio) -{ - TRectype da(LF_MOV); - TRectype a(LF_MOV); - da.put(MOV_DATAREG, _dataini); - a.put(MOV_DATAREG, _datafin); - TRelation rel(LF_MOV); - rel.add(LF_RMOVIVA, "NUMREG==NUMREG", 1); - rel.add("REG", "CODTAB[1,4]==ANNOIVA|CODTAB[5,7]==REG", 1); - rel.add(LF_CLIFO, "TIPOCF==TIPO|CODCF==CODCF", 1); - TCursor cur(&rel, "", 2, &da, &a); - const long cur_items = cur.items(); - if (cur_items != 0) - - { - cur.freeze(); - TRectype& cur_rec = cur.curr(); - for (cur = 0; cur.pos() < cur_items; ++(cur)) - { - const long numreg = cur.curr().get_long(MOV_NUMREG); - bool continua = TRUE; - while (continua) - { - const long numregrig = cur.curr(LF_RMOVIVA).get_long(RMI_NUMREG); - if (numreg == numregrig) - { - if (invio) - { - TRectype& cur_rec_righe = cur.curr(LF_RMOVIVA); - TRecord_text recrighe; - recrighe.set_type("I"); - _trasfile->autoload(recrighe, cur); - _trasfile->write(recrighe); - } - } - continua = cur.next_match(LF_RMOVIVA, "NUMREG"); - } - } - } - return 0; -} - -long TInvioS::i_sispac_clifor(const char* tipocf, const bool invio) -{ - TString80 nomefile = "FILE"; - nomefile << tipocf; - TInvioS_file* trasfilecf = apri_file(_configfile->get(nomefile, "OPZIONI")); - TRelation rel(LF_CLIFO); - rel.add(LF_COMUNI, "STATO==STATOCF|COM==COMCF", 1); - rel.add(LF_ANAGFIS,"CODANAGR==CODANAGPER", 1); - rel.add(LF_ANAG,"TIPOA==TIPOPERS|CODANAGR==CODANAGPER", 1); - TString80 filtro; - filtro = "20->TIPOCF == \""; - filtro << tipocf; - filtro << "\""; - TCursor cur(&rel); - cur.setfilter(filtro, TRUE); - const long cur_items = cur.items(); - if (cur_items != 0 && invio) - { - cur.freeze(); - TRectype& cur_rec = cur.curr(); - for (cur = 0; cur.pos() < cur_items; ++(cur)) - { - TRecord_text rec; - rec.set_type(tipocf); - trasfilecf->autoload(rec, cur); - trasfilecf->write(rec); - } - } - chiudi_file(trasfilecf); - return 0; -} - -//metodone globale che chiama, come un menu, i vari sottometodi in base alle scelte sulla maschera -void TInvioS::invio_sispac() -{ - if (_msk->get_bool(F_CLIFOR)) - { - i_sispac_clifor("C"); - i_sispac_clifor("F"); - } - if (_msk->get_bool(F_MOVCONT)) - { - TString80 filename = _configfile->get("FILEM", "OPZIONI"); - _trasfile = apri_file(filename); - i_sispac_movcont(); - i_sispac_moviva(); - chiudi_file(_trasfile); - } -} - -bool TInvioS::create() -{ - _msk = new TInvioS_mask(); - TFilename configname = "tc9200conf.ini"; - configname.custom_path(); - _configfile = new TConfig(configname); - return TSkeleton_application::create(); -} - -bool TInvioS::destroy() -{ - delete _configfile; - delete _msk; - return TSkeleton_application::destroy(); -} - -void TInvioS::main_loop() -{ - _msk->set(F_NUMEROINVIO, _configfile->get_int("NUMEROINVIO","OPZIONI")+1); - _msk->set(F_DATAINI, _configfile->get("DATA","OPZIONI")); - _msk->set(F_DESTINAZIONE, _configfile->get("PERCORSO","OPZIONI")); - while (_msk->run() != K_QUIT) - { - _configfile->set("NUMEROINVIO", _msk->get(F_NUMEROINVIO),"OPZIONI"); - _configfile->set("DATA", _msk->get_date(F_DATAFIN),"OPZIONI"); - _configfile->set("PERCORSO", _msk->get(F_DESTINAZIONE),"OPZIONI"); - _configfile->set_paragraph("PAGAMENTI"); - _dataini = _msk->get_date(F_DATAINI); - _datafin = _msk->get_date(F_DATAFIN); - const char tipoinvio = _msk->get(F_TIPOINVIO)[0]; - if (tipoinvio == 'S') - invio_sispac(); - } -} +//NON riportare nulla!!!! Esiste dalla 4.0; qui e' solo un segnaposto +#include "tc9.h" int tc9200(int argc, char **argv) { - TInvioS a; - a.run(argc, argv, "Invio dati contabilitą Sispac/Cosmo"); - return 0; + return 0; } - diff --git a/tc/tcconf.h b/tc/tcconf.h index 84f459f5c..47ae42912 100755 --- a/tc/tcconf.h +++ b/tc/tcconf.h @@ -17,13 +17,20 @@ #define F_USECMPCN 126 #define F_SHEET_IVA 127 #define F_SHEET_RIT 128 +#define F_EMCAU 129 +#define F_SHEET_ATTIV 130 +#define F_PROFESS 131 -#define SI_GRUPPO 101 -#define SI_CONTO 102 -#define SI_SOTTOCONTO 103 -#define SI_DESCR 104 -#define SI_SELECTOR 105 +#define SI_GRUPPO 101 +#define SI_CONTO 102 +#define SI_SOTTOCONTO 103 +#define SI_DESCR 104 +#define SI_SELECTOR 105 #define SI2_GRUPPO 201 #define SI2_CONTO 202 #define SI2_SOTTOCONTO 203 + +#define FR_ATTIV 101 +#define FR_DESCR 102 +#define FR_DITTATS 103 diff --git a/tc/tctscau.uml b/tc/tctscau.uml index 4e68ab96b..97fd1c72a 100755 --- a/tc/tctscau.uml +++ b/tc/tctscau.uml @@ -6,7 +6,7 @@ TOOLBAR "" 0 -3 0 3 ENDPAGE -PAGE "@bCausali" -1 -1 78 15 +PAGE "Causali" -1 -1 78 15 GROUPBOX DLG_NULL 78 3 BEGIN @@ -44,15 +44,18 @@ END STRING F_DESC 50 BEGIN PROMPT 10 2 "Descrizione " - FIELD S0 - USE NAZ KEY 2 - INPUT S0 F_DESC - DISPLAY "Descrizione@50" S0 - DISPLAY "Codice" CODTAB + USE LF_MULTIREL KEY 2 + INPUT COD F_COD SELECT + INPUT DATA F_DESC + DISPLAY "Descrizione@60" DATA + DISPLAY "Codice" FIRST + DISPLAY "Causale Collegata" SECOND COPY OUTPUT F_CODTAB - KEY 2 + FIELD DATA + KEY 3 CHECKTYPE REQUIRED END + STRING F_COD_CAMPO 3 BEGIN PROMPT 2 4 "Causale collegata " diff --git a/tc/tctscdp.uml b/tc/tctscdp.uml index 3c26825b2..575c454cb 100755 --- a/tc/tctscdp.uml +++ b/tc/tctscdp.uml @@ -6,7 +6,7 @@ TOOLBAR "" 0 -3 0 3 ENDPAGE -PAGE "@bCondizioni di pagamento" -1 -1 78 15 +PAGE "Condizioni di pagamento" -1 -1 78 15 GROUPBOX DLG_NULL 78 3 BEGIN @@ -44,13 +44,15 @@ END STRING F_DESC 50 BEGIN PROMPT 10 2 "Descrizione " - FIELD S0 - USE NAZ KEY 2 - INPUT S0 F_DESC - DISPLAY "Descrizione@50" S0 - DISPLAY "Codice" CODTAB + USE LF_MULTIREL KEY 2 + INPUT COD F_COD SELECT + INPUT DATA F_DESC + DISPLAY "Descrizione@60" DATA + DISPLAY "Codice" FIRST + DISPLAY "Condizione collegata" SECOND COPY OUTPUT F_CODTAB - KEY 2 + FIELD DATA + KEY 3 CHECKTYPE REQUIRED END diff --git a/tc/tctsnaz.uml b/tc/tctsnaz.uml index 0dde2ae4a..3f3fcf1ec 100755 --- a/tc/tctsnaz.uml +++ b/tc/tctsnaz.uml @@ -6,7 +6,7 @@ TOOLBAR "" 0 -3 0 3 ENDPAGE -PAGE "@bNazioni" -1 -1 78 15 +PAGE "Nazioni" -1 -1 78 15 GROUPBOX DLG_NULL 78 3 BEGIN @@ -44,13 +44,28 @@ END STRING F_DESC 50 BEGIN PROMPT 10 2 "Descrizione " - FIELD S0 - USE NAZ KEY 2 - INPUT S0 F_DESC - DISPLAY "Descrizione@50" S0 - DISPLAY "Codice" CODTAB + USE LF_MULTIREL KEY 2 + INPUT COD F_COD SELECT + INPUT DATA F_DESC + DISPLAY "Descrizione@60" DATA + DISPLAY "Codice" FIRST + DISPLAY "Stato collegato" SECOND COPY OUTPUT F_CODTAB - KEY 2 + FIELD DATA + KEY 3 + CHECKTYPE REQUIRED +END + +NUMBER F_COD_CAMPO 3 +BEGIN + PROMPT 2 4 "Stato collegato " + FIELD SECOND + FLAGS "Z" + USE %STA + INPUT CODTAB F_COD_CAMPO + DISPLAY "Cod." CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT F_COD_CAMPO CODTAB CHECKTYPE REQUIRED KEY 1 CHECKTYPE NORMAL diff --git a/tc/tctsreg.uml b/tc/tctsreg.uml index aefff0a65..6e13c2f03 100755 --- a/tc/tctsreg.uml +++ b/tc/tctsreg.uml @@ -6,11 +6,11 @@ TOOLBAR "" 0 -3 0 3 ENDPAGE -PAGE "@bRegistri" -1 -1 78 15 +PAGE "Registri" -1 -1 78 15 GROUPBOX DLG_NULL 78 3 BEGIN - PROMPT 1 1 "Registro" + PROMPT 1 1 "Registro TeamSystem" END LIST F_COD 5 @@ -49,19 +49,55 @@ BEGIN OUTPUT F_COD_CAMPO SECOND OUTPUT F_COD_CAMPO1 SECOND CHECKTYPE REQUIRED + FIELD FIRST[2,3] KEY 1 END -STRING F_DESC 50 +STRING F_DESC 50 40 BEGIN - PROMPT 10 2 "Descrizione " - FIELD S0 - USE NAZ KEY 2 - INPUT S0 F_DESC - DISPLAY "Descrizione@50" S0 - DISPLAY "Codice" CODTAB + PROMPT 25 2 "Descrizione " + USE LF_MULTIREL KEY 2 + INPUT COD F_COD SELECT + INPUT DATA F_DESC + DISPLAY "Descrizione@60" DATA + DISPLAY "Tipo" FIRST[1,1] + DISPLAY "Codice" FIRST[2,3] + DISPLAY "Codice registro" SECOND COPY OUTPUT F_CODTAB - KEY 2 + FIELD DATA + KEY 3 + CHECKTYPE REQUIRED +END + +NUMBER F_ANNO 4 +BEGIN + PROMPT 2 5 "" + FLAGS "AH" +END + +NUMBER F_TIPOREG 1 +BEGIN + PROMPT 2 5 "" + FLAGS "H" +END + +STRING F_CORRISP 1 +BEGIN + PROMPT 2 5 "" + FLAGS "H" +END + +STRING F_COD_CAMPO 3 +BEGIN + PROMPT 2 4 "Registro collegato " + FIELD SECOND + FLAGS "GUZ" + USE REG SELECT (I0==#F_TIPOREG) + INPUT CODTAB[1,4] F_ANNO SELECT + INPUT CODTAB[5,7] F_COD_CAMPO + DISPLAY "Codice" CODTAB[5,7] + DISPLAY "Descrizione@50" S0 + OUTPUT F_COD_CAMPO CODTAB[5,7] CHECKTYPE REQUIRED KEY 1 CHECKTYPE NORMAL diff --git a/tp/tp0100.cpp b/tp/tp0100.cpp index 8cee41b43..fd4fca5e4 100755 --- a/tp/tp0100.cpp +++ b/tp/tp0100.cpp @@ -462,6 +462,8 @@ void TTrasferimentoPack_mask::trasferisci() pc.activate_ref_info(get_bool(F_REFINFO)); pc.activate_cmsref(get_bool(F_CMSREF));; pc.set_data_limite(get_date(F_DATABOLLE)); + pc.activate_order_paper_info(get_bool(F_ORDPAPER)); + pc.activate_extended_discount(get_bool(F_DISCOUNT)); pc.init(TR("Documenti di trasporto"), query_header, log); go_on = pc.trasferisci(); book.add(log); diff --git a/tp/tp0100.h b/tp/tp0100.h index f3606b2f5..1508576c7 100755 --- a/tp/tp0100.h +++ b/tp/tp0100.h @@ -170,7 +170,8 @@ class TPack_ddt : public TPack_transfer { TCache_art* _art; TCache_umart* _umart; - bool _cust_ref, _paper_info, _ref_info, _cust_code, _cms_ref; + bool _cust_ref, _paper_info, _ref_info, _cust_code; + bool _cms_ref, _order_paper_info, _extended_discount; TDate _data_limite; TAssoc_array _iva; // Codici IVA PACK @@ -184,18 +185,21 @@ protected: const TRectype& get_articolo(TString& um, real& qta, TString& custcode); const TString& get_codice_iva(); const TString& get_customer_reference() const; + bool get_paper_from_order(TString& desc) const; bool save_doc(TDocumento* &doc, const int doc_code); public: virtual bool trasferisci(); - void activate_custref(bool on) { _cust_ref = on; } - void activate_paper_info(bool on) { _paper_info = on; } - void activate_ref_info(bool on) { _ref_info = on; } - void activate_cmsref(bool on) { _cms_ref = on; } - void set_data_limite(const TDate& data) { _data_limite = data; } + void activate_custref(bool on) { _cust_ref = on; } + void activate_paper_info(bool on) { _paper_info = on; } + void activate_ref_info(bool on) { _ref_info = on; } + void activate_cmsref(bool on) { _cms_ref = on; } + void set_data_limite(const TDate& data) { _data_limite = data; } void activate_customer_code(bool on); + void activate_order_paper_info(bool on) { _order_paper_info = on; } + void activate_extended_discount(bool on) { _extended_discount = on; } TPack_ddt(); ~TPack_ddt(); diff --git a/tp/tp0100a.h b/tp/tp0100a.h index 1f6609c09..0ff1e537e 100755 --- a/tp/tp0100a.h +++ b/tp/tp0100a.h @@ -19,6 +19,8 @@ #define F_CUSTCODE 212 #define F_REFINFO 213 #define F_CMSREF 214 +#define F_ORDPAPER 215 +#define F_DISCOUNT 216 #endif diff --git a/tp/tp0100a.uml b/tp/tp0100a.uml index e44356631..e4f63882a 100755 --- a/tp/tp0100a.uml +++ b/tp/tp0100a.uml @@ -96,7 +96,7 @@ BEGIN FLAGS "*" END -GROUPBOX DLG_NULL 68 7 +GROUPBOX DLG_NULL 78 9 BEGIN PROMPT 1 6 "@bDocumenti di trasporto" END @@ -126,6 +126,15 @@ BEGIN PROMPT 2 11 "Utilizzare il codice articolo del cliente (Richiede tipo riga 14)" END +BOOLEAN F_ORDPAPER +BEGIN + PROMPT 2 12 "Descrizione articoli come da eventuale ordine" +END + +BOOLEAN F_DISCOUNT +BEGIN + PROMPT 2 13 "Gestione sconti di riga multipli" +END ENDPAGE diff --git a/tp/tp0102.cpp b/tp/tp0102.cpp index cb9cca2bb..0b372a65d 100755 --- a/tp/tp0102.cpp +++ b/tp/tp0102.cpp @@ -378,9 +378,33 @@ const TString& TPack_ddt::get_customer_reference() const return hcr; } +bool TPack_ddt::get_paper_from_order(TString& desc) const +{ + const TString16 ndoc = get_str("CDocNumber"); + const long nrow = get_long("CDocRow"); + if (ndoc.blank() || nrow <= 0) + return false; + + TString qry(256); + qry << query_header(); + qry << "SELECT Paper_Composition_Group.CompDesc\n" + "FROM CDoc_Rows, Paper_Composition_Group\n" + "WHERE (CDoc_Rows.DocNumber=#NDOC)AND(CDoc_Rows.RowNumber=#NROW)" + "AND(CDoc_Rows.CompCode=Paper_Composition_Group.CompCode)"; + + TODBC_recordset paper(qry); + paper.set_var("#NDOC", TVariant(ndoc)); + paper.set_var("#NROW", TVariant(nrow)); + + if (paper.move_first()) + desc = paper.get(0u).as_string(); + + return desc.full(); +} + bool TPack_ddt::trasferisci() { - const char* query = + TString query = "SELECT DISTINCT " "PDdT_Header.DocCode, PDdT_Header.StoreDocType, PDdT_Header.DocRefNumber, " "PDdT_Header.DocDate, Store_Year.SyReferenceYear, PDdT_Header.CustSuppCode, " @@ -397,7 +421,8 @@ bool TPack_ddt::trasferisci() "Customers_Suppliers_2.TradeName1, Customers_Suppliers_2.Address, Customers_Suppliers_2.Locality, " "Customers_Suppliers_2.ZipCode, Customers_Suppliers_2.Region, PDdT_Row.DocRow, PDdT_Row.ArtCode, " "PDdT_Row.ArtDesc, PDdT_Row.CDocNumber, PDdT_Row.CDocRow, CDoc_Rows.CustReference AS RowCustReference ,CDoc_Header.CustReference, PDdT_Row.Provv, " - "PDdT_Row.DiscountRowDesc, PDdT_Row.Quantity, Unit_Measure.UMDesc, PDdT_Row.Quantity1, Unit_Measure_1.UMDesc AS UMDesc1, " + "PDdT_Row.DiscountRowDesc, " /* "PDdT_Row.Discount2, PDdT_Row.Discount3, " */ + "PDdT_Row.Quantity, Unit_Measure.UMDesc, PDdT_Row.Quantity1, Unit_Measure_1.UMDesc AS UMDesc1, " "PDdT_Row.Quantity2, Unit_Measure_2.UMDesc AS UMDesc2, PDdT_Row.AdvanceSale, PDdT_Row.Price, " "PDdT_Row.DefPrice, PDdT_Row.PriceNet, PDdT_Row.PriceNetDef, PDdT_Row.AmountNet, PDdT_Row.AmountNetDef, " "PDdT_Row.Amount, PDdT_Row.AmountDef, PDdT_Row.FlagUMPrice, IVA.IVACode, PDdT_Row.AccountCode, " @@ -427,7 +452,16 @@ bool TPack_ddt::trasferisci() "WHERE (((PDdT_Row.DDTRowType)='0' Or (PDdT_Row.DDTRowType)='2') AND " "((PDdT_Header.StatusFlag)='1' OR (PDdT_Header.StatusFlag)='2' Or (PDdT_Header.StatusFlag)='3') AND " "((select case when [Modalitą Fornitura Bancali].[Value1] is null then 1 else [Modalitą Fornitura Bancali].[Value1] end)=1) AND " - "((PDdT_Header.InvoicingType) Is Not Null) AND ((PDdT_Header.DocProvv)<>-1))"; + "((PDdT_Header.InvoicingType) Is Not Null) AND ((PDdT_Header.DocProvv)<>-1))" + "\nORDER BY PDdT_Header.DocRefNumber, PDdT_Row.DocRow" + ; + + if (_extended_discount) + { + const TFixed_string discount("PDdT_Row.DiscountRowDesc, "); + const int pos = query.find(discount); + query.insert("PDdT_Row.Discount2, PDdT_Row.Discount3, ", pos+discount.len()); + } TRecordset& recset = create_recordset(query); TDocumento* doc = NULL; @@ -549,12 +583,18 @@ bool TPack_ddt::trasferisci() TString descr = get_str("ArtDesc"); const bool bIsSingleSheet = bIsMerce && get_long("ArtType") == 4; // Foglio singolo? - if (bIsSingleSheet && descr.find('(') < 0) // E' un foglio singolo senza dimensioni? + if (bIsSingleSheet) { - TString80 misure; - misure << get_str("Height") << " x " << get_str("Width"); - if (misure[0] > '0') - descr << " (" << misure << ')'; + if (_order_paper_info) + get_paper_from_order(descr); + + if (bIsSingleSheet && descr.find('(') < 0) // E' un foglio singolo senza dimensioni? + { + TString80 misure; + misure << get_str("Height") << " x " << get_str("Width"); + if (misure[0] > '0') + descr << " (" << misure << ')'; + } } if (descr.len() <= 50) @@ -579,9 +619,17 @@ bool TPack_ddt::trasferisci() rdoc.put(RDOC_QTA, qta); rdoc.put(RDOC_CODIVA, get_codice_iva()); rdoc.put(RDOC_PREZZO, get_real_str("Price")); - rdoc.put(RDOC_SCONTO, get_real_str("DiscountRowDesc")); - rdoc.put(RDOC_PERCPROV, get_real_str("Provv")); + TString sconto = get_real_str("DiscountRowDesc"); + if (_extended_discount) + { + sconto << ' ' << get_real_str("Discount2"); + sconto << ' ' << get_real_str("Discount3"); + sconto.trim(); sconto.replace(' ', '+'); + } + rdoc.put(RDOC_SCONTO, sconto); + + rdoc.put(RDOC_PERCPROV, get_real_str("Provv")); rdoc.put(RDOC_QTAGG1, get_real_str("WeightETUnit")); rdoc.zero(RDOC_QTAGG2); // Azzera percentuale indetraibilita' CONAI if (bIsSingleSheet) @@ -604,7 +652,7 @@ bool TPack_ddt::trasferisci() TString info; if (_paper_info) { - info << art.get(ANAMAG_USER10); + info = art.get(ANAMAG_USER10); if (info.full()) info.insert("\n"); diff --git a/xvaga/MD5Checksum.cpp b/xvaga/MD5Checksum.cpp new file mode 100755 index 000000000..f4d0b4241 --- /dev/null +++ b/xvaga/MD5Checksum.cpp @@ -0,0 +1,536 @@ +/***************************************************************************************** + +*** MD5Checksum.cpp: implementation of the MD5Checksum class. + +*** Developed by Langfine Ltd. +*** Released to the public domain 12/Nov/2001. +*** Please visit our website www.langfine.com + +*** Any modifications must be clearly commented to distinguish them from Langfine's +*** original source code. Please advise Langfine of useful modifications so that we +*** can make them generally available. + +*****************************************************************************************/ + + +/**************************************************************************************** +This software is derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm. +Incorporation of this statement is a condition of use; please see the RSA +Data Security Inc copyright notice below:- + +Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All +rights reserved. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. + +Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. +*****************************************************************************************/ + +/**************************************************************************************** +This implementation of the RSA MD5 Algorithm was written by Langfine Ltd +(www.langfine.com). + +Langfine Ltd makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +In addition to the above, Langfine make no warrant or assurances regarding the +accuracy of this implementation of the MD5 checksum algorithm nor any assurances regarding +its suitability for any purposes. + +This implementation may be used freely provided that Langfine is credited +in a copyright or similar notices (eg, RSA MD5 Algorithm implemented by Langfine +Ltd.) and provided that the RSA Data Security notices are complied with. +*/ + + +#include "wxinc.h" + +#include "MD5Checksum.h" +#include "MD5ChecksumDefines.h" + +#include +#include "wx/filename.h" + + +/***************************************************************************************** +FUNCTION: wxMD5Checksum::GetMD5 +DETAILS: static, public +DESCRIPTION: Gets the MD5 checksum for a specified file +RETURNS: wxString : the hexadecimal MD5 checksum for the specified file +ARGUMENTS: wxString& strFilePath : the full pathname of the specified file +NOTES: Provides an interface to the wxMD5Checksum class. 'strFilePath' name should + hold the full pathname of the file, eg C:\My Documents\Arcticle.txt. + NB. If any problems occur with opening or reading this file, a CFileException + will be thrown; callers of this function should be ready to catch this + exception. +*****************************************************************************************/ +wxString wxMD5Checksum::GetMD5(const wxString& strFilePath) +{ + if(!wxFileName::FileExists(strFilePath)) + return wxEmptyString; + + //open the file as a binary file in readonly mode, denying write access + wxFile File(strFilePath, wxFile::read); + //the file has been successfully opened, so now get and return its checksum + return GetMD5(File); +} + + +/***************************************************************************************** +FUNCTION: wxMD5Checksum::GetMD5 +DETAILS: static, public +DESCRIPTION: Gets the MD5 checksum for a specified file +RETURNS: wxString : the hexadecimal MD5 checksum for the specified file +ARGUMENTS: wxFile& File : the specified file +NOTES: Provides an interface to the wxMD5Checksum class. 'File' should be open in + binary readonly mode before calling this function. + NB. Callers of this function should be ready to catch any CFileException + thrown by the wxFile functions +*****************************************************************************************/ +wxString wxMD5Checksum::GetMD5(wxFile& File) +{ + wxMD5Checksum MD5Checksum; //checksum object + int nLength = 0; //number of bytes read from the file + const int nBufferSize = 1024; //checksum the file in blocks of 1024 bytes + unsigned char Buffer[nBufferSize]; //buffer for data read from the file + + //checksum the file in blocks of 1024 bytes + while ((nLength = File.Read( Buffer, nBufferSize )) > 0 ) + { + MD5Checksum.Update( Buffer, nLength ); + } + + //finalise the checksum and return it + return MD5Checksum.Final(); + +} + + +/***************************************************************************************** +FUNCTION: wxMD5Checksum::GetMD5 +DETAILS: static, public +DESCRIPTION: Gets the MD5 checksum for data in a unsigned char array +RETURNS: wxString : the hexadecimal MD5 checksum for the specified data +ARGUMENTS: unsigned char* pBuf : pointer to the unsigned char array + unsigned int nLength : number of BYTEs of data to be checksumed +NOTES: Provides an interface to the wxMD5Checksum class. Any data that can + be cast to a unsigned char array of known length can be checksummed by this + function. Typically, wxString and char arrays will be checksumed, + although this function can be used to check the integrity of any unsigned char array. + A buffer of zero length can be checksummed; all buffers of zero length + will return the same checksum. +*****************************************************************************************/ +wxString wxMD5Checksum::GetMD5(unsigned char* pBuf, unsigned int nLength) +{ + //calculate and return the checksum + wxMD5Checksum MD5Checksum; + MD5Checksum.Update( pBuf, nLength ); + return MD5Checksum.Final(); +} + + +/***************************************************************************************** +FUNCTION: wxMD5Checksum::RotateLeft +DETAILS: private +DESCRIPTION: Rotates the bits in a 32 bit unsigned long left by a specified amount +RETURNS: The rotated unsigned long +ARGUMENTS: unsigned long x : the value to be rotated + int n : the number of bits to rotate by +*****************************************************************************************/ +unsigned long wxMD5Checksum::RotateLeft(unsigned long x, int n) +{ + //check that unsigned long is 4 bytes long - true in Visual C++ 6 and 32 bit Windows + wxASSERT( sizeof(x) == 4 ); + + //rotate and return x + return (x << n) | (x >> (32-n)); +} + + +/***************************************************************************************** +FUNCTION: wxMD5Checksum::FF +DETAILS: protected +DESCRIPTION: Implementation of basic MD5 transformation algorithm +RETURNS: none +ARGUMENTS: unsigned long &A, B, C, D : Current (partial) checksum + unsigned long X : Input data + unsigned long S : MD5_SXX Transformation constant + unsigned long T : MD5_TXX Transformation constant +NOTES: None +*****************************************************************************************/ +void wxMD5Checksum::FF( unsigned long& A, unsigned long B, unsigned long C, unsigned long D, unsigned long X, unsigned long S, unsigned long T) +{ + unsigned long F = (B & C) | (~B & D); + A += F + X + T; + A = RotateLeft(A, S); + A += B; +} + + +/***************************************************************************************** +FUNCTION: wxMD5Checksum::GG +DETAILS: protected +DESCRIPTION: Implementation of basic MD5 transformation algorithm +RETURNS: none +ARGUMENTS: unsigned long &A, B, C, D : Current (partial) checksum + unsigned long X : Input data + unsigned long S : MD5_SXX Transformation constant + unsigned long T : MD5_TXX Transformation constant +NOTES: None +*****************************************************************************************/ +void wxMD5Checksum::GG( unsigned long& A, unsigned long B, unsigned long C, unsigned long D, unsigned long X, unsigned long S, unsigned long T) +{ + unsigned long G = (B & D) | (C & ~D); + A += G + X + T; + A = RotateLeft(A, S); + A += B; +} + + +/***************************************************************************************** +FUNCTION: wxMD5Checksum::HH +DETAILS: protected +DESCRIPTION: Implementation of basic MD5 transformation algorithm +RETURNS: none +ARGUMENTS: unsigned long &A, B, C, D : Current (partial) checksum + unsigned long X : Input data + unsigned long S : MD5_SXX Transformation constant + unsigned long T : MD5_TXX Transformation constant +NOTES: None +*****************************************************************************************/ +void wxMD5Checksum::HH( unsigned long& A, unsigned long B, unsigned long C, unsigned long D, unsigned long X, unsigned long S, unsigned long T) +{ + unsigned long H = (B ^ C ^ D); + A += H + X + T; + A = RotateLeft(A, S); + A += B; +} + + +/***************************************************************************************** +FUNCTION: wxMD5Checksum::II +DETAILS: protected +DESCRIPTION: Implementation of basic MD5 transformation algorithm +RETURNS: none +ARGUMENTS: unsigned long &A, B, C, D : Current (partial) checksum + unsigned long X : Input data + unsigned long S : MD5_SXX Transformation constant + unsigned long T : MD5_TXX Transformation constant +NOTES: None +*****************************************************************************************/ +void wxMD5Checksum::II( unsigned long& A, unsigned long B, unsigned long C, unsigned long D, unsigned long X, unsigned long S, unsigned long T) +{ + unsigned long I = (C ^ (B | ~D)); + A += I + X + T; + A = RotateLeft(A, S); + A += B; +} + + +/***************************************************************************************** +FUNCTION: wxMD5Checksum::ByteToDWord +DETAILS: private +DESCRIPTION: Transfers the data in an 8 bit array to a 32 bit array +RETURNS: void +ARGUMENTS: unsigned long* Output : the 32 bit (unsigned long) destination array + unsigned char* Input : the 8 bit (unsigned char) source array + unsigned int nLength : the number of 8 bit data items in the source array +NOTES: Four BYTES from the input array are transferred to each unsigned long entry + of the output array. The first unsigned char is transferred to the bits (0-7) + of the output unsigned long, the second unsigned char to bits 8-15 etc. + The algorithm assumes that the input array is a multiple of 4 bytes long + so that there is a perfect fit into the array of 32 bit words. +*****************************************************************************************/ +void wxMD5Checksum::ByteToDWord(unsigned long* Output, unsigned char* Input, unsigned int nLength) +{ + //entry invariants + wxASSERT( nLength % 4 == 0 ); + + //initialisations + unsigned int i=0; //index to Output array + unsigned int j=0; //index to Input array + + //transfer the data by shifting and copying + for ( ; j < nLength; i++, j += 4) + { + Output[i] = (unsigned long)Input[j] | + (unsigned long)Input[j+1] << 8 | + (unsigned long)Input[j+2] << 16 | + (unsigned long)Input[j+3] << 24; + } +} + +/***************************************************************************************** +FUNCTION: wxMD5Checksum::Transform +DETAILS: protected +DESCRIPTION: MD5 basic transformation algorithm; transforms 'm_lMD5' +RETURNS: void +ARGUMENTS: unsigned char Block[64] +NOTES: An MD5 checksum is calculated by four rounds of 'Transformation'. + The MD5 checksum currently held in m_lMD5 is merged by the + transformation process with data passed in 'Block'. +*****************************************************************************************/ +void wxMD5Checksum::Transform(unsigned char Block[64]) +{ + //initialise local data with current checksum + unsigned long a = m_lMD5[0]; + unsigned long b = m_lMD5[1]; + unsigned long c = m_lMD5[2]; + unsigned long d = m_lMD5[3]; + + //copy BYTES from input 'Block' to an array of ULONGS 'X' + unsigned long X[16]; + ByteToDWord( X, Block, 64 ); + + //Perform Round 1 of the transformation + FF (a, b, c, d, X[ 0], MD5_S11, MD5_T01); + FF (d, a, b, c, X[ 1], MD5_S12, MD5_T02); + FF (c, d, a, b, X[ 2], MD5_S13, MD5_T03); + FF (b, c, d, a, X[ 3], MD5_S14, MD5_T04); + FF (a, b, c, d, X[ 4], MD5_S11, MD5_T05); + FF (d, a, b, c, X[ 5], MD5_S12, MD5_T06); + FF (c, d, a, b, X[ 6], MD5_S13, MD5_T07); + FF (b, c, d, a, X[ 7], MD5_S14, MD5_T08); + FF (a, b, c, d, X[ 8], MD5_S11, MD5_T09); + FF (d, a, b, c, X[ 9], MD5_S12, MD5_T10); + FF (c, d, a, b, X[10], MD5_S13, MD5_T11); + FF (b, c, d, a, X[11], MD5_S14, MD5_T12); + FF (a, b, c, d, X[12], MD5_S11, MD5_T13); + FF (d, a, b, c, X[13], MD5_S12, MD5_T14); + FF (c, d, a, b, X[14], MD5_S13, MD5_T15); + FF (b, c, d, a, X[15], MD5_S14, MD5_T16); + + //Perform Round 2 of the transformation + GG (a, b, c, d, X[ 1], MD5_S21, MD5_T17); + GG (d, a, b, c, X[ 6], MD5_S22, MD5_T18); + GG (c, d, a, b, X[11], MD5_S23, MD5_T19); + GG (b, c, d, a, X[ 0], MD5_S24, MD5_T20); + GG (a, b, c, d, X[ 5], MD5_S21, MD5_T21); + GG (d, a, b, c, X[10], MD5_S22, MD5_T22); + GG (c, d, a, b, X[15], MD5_S23, MD5_T23); + GG (b, c, d, a, X[ 4], MD5_S24, MD5_T24); + GG (a, b, c, d, X[ 9], MD5_S21, MD5_T25); + GG (d, a, b, c, X[14], MD5_S22, MD5_T26); + GG (c, d, a, b, X[ 3], MD5_S23, MD5_T27); + GG (b, c, d, a, X[ 8], MD5_S24, MD5_T28); + GG (a, b, c, d, X[13], MD5_S21, MD5_T29); + GG (d, a, b, c, X[ 2], MD5_S22, MD5_T30); + GG (c, d, a, b, X[ 7], MD5_S23, MD5_T31); + GG (b, c, d, a, X[12], MD5_S24, MD5_T32); + + //Perform Round 3 of the transformation + HH (a, b, c, d, X[ 5], MD5_S31, MD5_T33); + HH (d, a, b, c, X[ 8], MD5_S32, MD5_T34); + HH (c, d, a, b, X[11], MD5_S33, MD5_T35); + HH (b, c, d, a, X[14], MD5_S34, MD5_T36); + HH (a, b, c, d, X[ 1], MD5_S31, MD5_T37); + HH (d, a, b, c, X[ 4], MD5_S32, MD5_T38); + HH (c, d, a, b, X[ 7], MD5_S33, MD5_T39); + HH (b, c, d, a, X[10], MD5_S34, MD5_T40); + HH (a, b, c, d, X[13], MD5_S31, MD5_T41); + HH (d, a, b, c, X[ 0], MD5_S32, MD5_T42); + HH (c, d, a, b, X[ 3], MD5_S33, MD5_T43); + HH (b, c, d, a, X[ 6], MD5_S34, MD5_T44); + HH (a, b, c, d, X[ 9], MD5_S31, MD5_T45); + HH (d, a, b, c, X[12], MD5_S32, MD5_T46); + HH (c, d, a, b, X[15], MD5_S33, MD5_T47); + HH (b, c, d, a, X[ 2], MD5_S34, MD5_T48); + + //Perform Round 4 of the transformation + II (a, b, c, d, X[ 0], MD5_S41, MD5_T49); + II (d, a, b, c, X[ 7], MD5_S42, MD5_T50); + II (c, d, a, b, X[14], MD5_S43, MD5_T51); + II (b, c, d, a, X[ 5], MD5_S44, MD5_T52); + II (a, b, c, d, X[12], MD5_S41, MD5_T53); + II (d, a, b, c, X[ 3], MD5_S42, MD5_T54); + II (c, d, a, b, X[10], MD5_S43, MD5_T55); + II (b, c, d, a, X[ 1], MD5_S44, MD5_T56); + II (a, b, c, d, X[ 8], MD5_S41, MD5_T57); + II (d, a, b, c, X[15], MD5_S42, MD5_T58); + II (c, d, a, b, X[ 6], MD5_S43, MD5_T59); + II (b, c, d, a, X[13], MD5_S44, MD5_T60); + II (a, b, c, d, X[ 4], MD5_S41, MD5_T61); + II (d, a, b, c, X[11], MD5_S42, MD5_T62); + II (c, d, a, b, X[ 2], MD5_S43, MD5_T63); + II (b, c, d, a, X[ 9], MD5_S44, MD5_T64); + + //add the transformed values to the current checksum + m_lMD5[0] += a; + m_lMD5[1] += b; + m_lMD5[2] += c; + m_lMD5[3] += d; +} + + +/***************************************************************************************** +CONSTRUCTOR: wxMD5Checksum +DESCRIPTION: Initialises member data +ARGUMENTS: None +NOTES: None +*****************************************************************************************/ +wxMD5Checksum::wxMD5Checksum() +{ + // zero members + memset( m_lpszBuffer, 0, 64 ); + m_nCount[0] = m_nCount[1] = 0; + + // Load magic state initialization constants + m_lMD5[0] = MD5_INIT_STATE_0; + m_lMD5[1] = MD5_INIT_STATE_1; + m_lMD5[2] = MD5_INIT_STATE_2; + m_lMD5[3] = MD5_INIT_STATE_3; +} + +/***************************************************************************************** +FUNCTION: wxMD5Checksum::DWordToByte +DETAILS: private +DESCRIPTION: Transfers the data in an 32 bit array to a 8 bit array +RETURNS: void +ARGUMENTS: unsigned char* Output : the 8 bit destination array + unsigned long* Input : the 32 bit source array + unsigned int nLength : the number of 8 bit data items in the source array +NOTES: One unsigned long from the input array is transferred into four BYTES + in the output array. The first (0-7) bits of the first unsigned long are + transferred to the first output unsigned char, bits bits 8-15 are transferred from + the second unsigned char etc. + + The algorithm assumes that the output array is a multiple of 4 bytes long + so that there is a perfect fit of 8 bit BYTES into the 32 bit DWORDs. +*****************************************************************************************/ +void wxMD5Checksum::DWordToByte(unsigned char* Output, unsigned long* Input, unsigned int nLength ) +{ + //entry invariants + wxASSERT( nLength % 4 == 0 ); + + //transfer the data by shifting and copying + unsigned int i = 0; + unsigned int j = 0; + for ( ; j < nLength; i++, j += 4) + { + Output[j] = (UCHAR)(Input[i] & 0xff); + Output[j+1] = (UCHAR)((Input[i] >> 8) & 0xff); + Output[j+2] = (UCHAR)((Input[i] >> 16) & 0xff); + Output[j+3] = (UCHAR)((Input[i] >> 24) & 0xff); + } +} + + +/***************************************************************************************** +FUNCTION: wxMD5Checksum::Final +DETAILS: protected +DESCRIPTION: Implementation of main MD5 checksum algorithm; ends the checksum calculation. +RETURNS: wxString : the final hexadecimal MD5 checksum result +ARGUMENTS: None +NOTES: Performs the final MD5 checksum calculation ('Update' does most of the work, + this function just finishes the calculation.) +*****************************************************************************************/ +wxString wxMD5Checksum::Final() +{ + //Save number of bits + unsigned char Bits[8]; + DWordToByte( Bits, m_nCount, 8 ); + + //Pad out to 56 mod 64. + unsigned int nIndex = (unsigned int)((m_nCount[0] >> 3) & 0x3f); + unsigned int nPadLen = (nIndex < 56) ? (56 - nIndex) : (120 - nIndex); + Update( PADDING, nPadLen ); + + //Append length (before padding) + Update( Bits, 8 ); + + //Store final state in 'lpszMD5' + const int nMD5Size = 16; + unsigned char lpszMD5[ nMD5Size ]; + DWordToByte( lpszMD5, m_lMD5, nMD5Size ); + + //Convert the hexadecimal checksum to a wxString + wxString strMD5; + for ( int i=0; i < nMD5Size; i++) + { + wxString Str; + if (lpszMD5[i] == 0) { + Str = wxT("00"); + } + else if (lpszMD5[i] <= 15) { + Str.Printf(wxT("0%x"),lpszMD5[i]); + } + else { + Str.Printf(wxT("%x"),lpszMD5[i]); + } + + wxASSERT( Str.Length() == 2 ); + strMD5 += Str; + } + wxASSERT( strMD5.Length() == 32 ); + return strMD5; +} + + +/***************************************************************************************** +FUNCTION: wxMD5Checksum::Update +DETAILS: protected +DESCRIPTION: Implementation of main MD5 checksum algorithm +RETURNS: void +ARGUMENTS: unsigned char* Input : input block + unsigned int nInputLen : length of input block +NOTES: Computes the partial MD5 checksum for 'nInputLen' bytes of data in 'Input' +*****************************************************************************************/ +void wxMD5Checksum::Update( unsigned char* Input, unsigned long nInputLen ) +{ + //Compute number of bytes mod 64 + unsigned int nIndex = (unsigned int)((m_nCount[0] >> 3) & 0x3F); + + //Update number of bits + if ( ( m_nCount[0] += nInputLen << 3 ) < ( nInputLen << 3) ) + { + m_nCount[1]++; + } + m_nCount[1] += (nInputLen >> 29); + + //Transform as many times as possible. + unsigned int i=0; + unsigned int nPartLen = 64 - nIndex; + if (nInputLen >= nPartLen) + { + memcpy( &m_lpszBuffer[nIndex], Input, nPartLen ); + Transform( m_lpszBuffer ); + for (i = nPartLen; i + 63 < nInputLen; i += 64) + { + Transform( &Input[i] ); + } + nIndex = 0; + } + else + { + i = 0; + } + + // Buffer remaining input + memcpy( &m_lpszBuffer[nIndex], &Input[i], nInputLen-i); +} + + diff --git a/xvaga/MD5Checksum.h b/xvaga/MD5Checksum.h new file mode 100755 index 000000000..c95a44eb4 --- /dev/null +++ b/xvaga/MD5Checksum.h @@ -0,0 +1,342 @@ +/***************************************************************************************** + +*** MD5Checksum.h: interface for the MD5Checksum class. + +*** Developed by Langfine Ltd. +*** Released to the public domain 12/Nov/2001. +*** Please visit our website www.langfine.com + +*** Any modifications must be clearly commented to distinguish them from Langfine's +*** original source code. Please advise Langfine of useful modifications so that we +*** can make them generally available. + +*****************************************************************************************/ + + +#ifndef __MD5CHECKSUM_H__ +#define __MD5CHECKSUM_H__ + +/**************************************************************************************** +This software is derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm. +Incorporation of this statement is a condition of use; please see the RSA +Data Security Inc copyright notice below:- + +Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All +rights reserved. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. + +Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. +*****************************************************************************************/ + +/**************************************************************************************** +This implementation of the RSA MD5 Algorithm was written by Langfine Ltd. + +Langfine Ltd makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +In addition to the above, Langfine make no warrant or assurances regarding the +accuracy of this implementation of the MD5 checksum algorithm nor any assurances regarding +its suitability for any purposes. + +This implementation may be used freely provided that Langfine is credited +in a copyright or similar notices (eg, RSA MD5 Algorithm implemented by Langfine +Ltd.) and provided that the RSA Data Security notices are complied with. + +Langfine may be contacted at mail@langfine.com +*/ + +/***************************************************************************************** +CLASS: wxMD5Checksum +DESCRIPTION: Implements the "RSA Data Security, Inc. MD5 Message-Digest Algorithm". +NOTES: Calculates the RSA MD5 checksum for a file or congiguous array of data. + +Below are extracts from a memo on The MD5 Message-Digest Algorithm by R. Rivest of MIT +Laboratory for Computer Science and RSA Data Security, Inc., April 1992. + + 1. Executive Summary + This document describes the MD5 message-digest algorithm. The + algorithm takes as input a message of arbitrary length and produces + as output a 128-bit "fingerprint" or "message digest" of the input. + It is conjectured that it is computationally infeasible to produce + two messages having the same message digest, or to produce any + message having a given prespecified target message digest. The MD5 + algorithm is intended for digital signature applications, where a + large file must be "compressed" in a secure manner before being + encrypted with a private (secret) key under a public-key cryptosystem + such as RSA. + + The MD5 algorithm is designed to be quite fast on 32-bit machines. In + addition, the MD5 algorithm does not require any large substitution + tables; the algorithm can be coded quite compactly. + The MD5 algorithm is an extension of the MD4 message-digest algorithm + 1,2]. MD5 is slightly slower than MD4, but is more "conservative" in + design. MD5 was designed because it was felt that MD4 was perhaps + being adopted for use more quickly than justified by the existing + critical review; because MD4 was designed to be exceptionally fast, + it is "at the edge" in terms of risking successful cryptanalytic + attack. MD5 backs off a bit, giving up a little in speed for a much + greater likelihood of ultimate security. It incorporates some + suggestions made by various reviewers, and contains additional + optimizations. The MD5 algorithm is being placed in the public domain + for review and possible adoption as a standard. + + + 2. Terminology and Notation + In this document a "word" is a 32-bit quantity and a "byte" is an + eight-bit quantity. A sequence of bits can be interpreted in a + natural manner as a sequence of bytes, where each consecutive group + of eight bits is interpreted as a byte with the high-order (most + significant) bit of each byte listed first. Similarly, a sequence of + bytes can be interpreted as a sequence of 32-bit words, where each + consecutive group of four bytes is interpreted as a word with the + low-order (least significant) byte given first. + Let x_i denote "x sub i". If the subscript is an expression, we + surround it in braces, as in x_{i+1}. Similarly, we use ^ for + superscripts (exponentiation), so that x^i denotes x to the i-th power. + Let the symbol "+" denote addition of words (i.e., modulo-2^32 + addition). Let X <<< s denote the 32-bit value obtained by circularly + shifting (rotating) X left by s bit positions. Let not(X) denote the + bit-wise complement of X, and let X v Y denote the bit-wise OR of X + and Y. Let X xor Y denote the bit-wise XOR of X and Y, and let XY + denote the bit-wise AND of X and Y. + + + 3. MD5 Algorithm Description + We begin by supposing that we have a b-bit message as input, and that + we wish to find its message digest. Here b is an arbitrary + nonnegative integer; b may be zero, it need not be a multiple of + eight, and it may be arbitrarily large. We imagine the bits of the + message written down as follows: m_0 m_1 ... m_{b-1} + The following five steps are performed to compute the message digest + of the message. + + 3.1 Step 1. Append Padding Bits + The message is "padded" (extended) so that its length (in bits) is + congruent to 448, modulo 512. That is, the message is extended so + that it is just 64 bits shy of being a multiple of 512 bits long. + Padding is always performed, even if the length of the message is + already congruent to 448, modulo 512. + Padding is performed as follows: a single "1" bit is appended to the + message, and then "0" bits are appended so that the length in bits of + the padded message becomes congruent to 448, modulo 512. In all, at + least one bit and at most 512 bits are appended. + + 3.2 Step 2. Append Length + A 64-bit representation of b (the length of the message before the + padding bits were added) is appended to the result of the previous + step. In the unlikely event that b is greater than 2^64, then only + the low-order 64 bits of b are used. (These bits are appended as two + 32-bit words and appended low-order word first in accordance with the + previous conventions.) + At this point the resulting message (after padding with bits and with + b) has a length that is an exact multiple of 512 bits. Equivalently, + this message has a length that is an exact multiple of 16 (32-bit) + words. Let M[0 ... N-1] denote the words of the resulting message, + where N is a multiple of 16. + + 3.3 Step 3. Initialize MD Buffer + A four-word buffer (A,B,C,D) is used to compute the message digest. + Here each of A, B, C, D is a 32-bit register. These registers are + initialized to the following values in hexadecimal, low-order bytes first): + word A: 01 23 45 67 word B: 89 ab cd ef + word C: fe dc ba 98 word D: 76 54 32 10 + + 3.4 Step 4. Process Message in 16-Word Blocks + We first define four auxiliary functions that each take as input + three 32-bit words and produce as output one 32-bit word. + F(X,Y,Z) = XY v not(X) Z G(X,Y,Z) = XZ v Y not(Z) + H(X,Y,Z) = X xor Y xor Z I(X,Y,Z) = Y xor (X v not(Z)) + In each bit position F acts as a conditional: if X then Y else Z. + The function F could have been defined using + instead of v since XY + and not(X)Z will never have 1's in the same bit position.) It is + interesting to note that if the bits of X, Y, and Z are independent + and unbiased, the each bit of F(X,Y,Z) will be independent and unbiased. + The functions G, H, and I are similar to the function F, in that they + act in "bitwise parallel" to produce their output from the bits of X, + Y, and Z, in such a manner that if the corresponding bits of X, Y, + and Z are independent and unbiased, then each bit of G(X,Y,Z), + H(X,Y,Z), and I(X,Y,Z) will be independent and unbiased. Note that + the function H is the bit-wise "xor" or "parity" function of its inputs. + This step uses a 64-element table T[1 ... 64] constructed from the + sine function. Let T[i] denote the i-th element of the table, which + is equal to the integer part of 4294967296 times abs(sin(i)), where i + is in radians. The elements of the table are given in the appendix. + Do the following: + + //Process each 16-word block. + For i = 0 to N/16-1 do // Copy block i into X. + For j = 0 to 15 do + Set X[j] to M[i*16+j]. + end //of loop on j + + // Save A as AA, B as BB, C as CC, and D as DD. + AA = A BB = B + CC = C DD = D + + // Round 1. + // Let [abcd k s i] denote the operation + // a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). + // Do the following 16 operations. + [ABCD 0 7 1] [DABC 1 12 2] [CDAB 2 17 3] [BCDA 3 22 4] + [ABCD 4 7 5] [DABC 5 12 6] [CDAB 6 17 7] [BCDA 7 22 8] + [ABCD 8 7 9] [DABC 9 12 10] [CDAB 10 17 11] [BCDA 11 22 12] + [ABCD 12 7 13] [DABC 13 12 14] [CDAB 14 17 15] [BCDA 15 22 16] + + // Round 2. + // Let [abcd k s i] denote the operation + // a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). + // Do the following 16 operations. + [ABCD 1 5 17] [DABC 6 9 18] [CDAB 11 14 19] [BCDA 0 20 20] + [ABCD 5 5 21] [DABC 10 9 22] [CDAB 15 14 23] [BCDA 4 20 24] + [ABCD 9 5 25] [DABC 14 9 26] [CDAB 3 14 27] [BCDA 8 20 28] + [ABCD 13 5 29] [DABC 2 9 30] [CDAB 7 14 31] [BCDA 12 20 32] + + // Round 3. + // Let [abcd k s t] denote the operation + // a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). + // Do the following 16 operations. + [ABCD 5 4 33] [DABC 8 11 34] [CDAB 11 16 35] [BCDA 14 23 36] + [ABCD 1 4 37] [DABC 4 11 38] [CDAB 7 16 39] [BCDA 10 23 40] + [ABCD 13 4 41] [DABC 0 11 42] [CDAB 3 16 43] [BCDA 6 23 44] + [ABCD 9 4 45] [DABC 12 11 46] [CDAB 15 16 47] [BCDA 2 23 48] + + // Round 4. + // Let [abcd k s t] denote the operation + // a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). + // Do the following 16 operations. + [ABCD 0 6 49] [DABC 7 10 50] [CDAB 14 15 51] [BCDA 5 21 52] + [ABCD 12 6 53] [DABC 3 10 54] [CDAB 10 15 55] [BCDA 1 21 56] + [ABCD 8 6 57] [DABC 15 10 58] [CDAB 6 15 59] [BCDA 13 21 60] + [ABCD 4 6 61] [DABC 11 10 62] [CDAB 2 15 63] [BCDA 9 21 64] + + // Then perform the following additions. (That is increment each + // of the four registers by the value it had before this block + // was started.) + A = A + AA B = B + BB C = C + CC D = D + DD + + end // of loop on i + + 3.5 Step 5. Output + The message digest produced as output is A, B, C, D. That is, we + begin with the low-order byte of A, and end with the high-order byte of D. + This completes the description of MD5. + + Summary + The MD5 message-digest algorithm is simple to implement, and provides + a "fingerprint" or message digest of a message of arbitrary length. + It is conjectured that the difficulty of coming up with two messages + having the same message digest is on the order of 2^64 operations, + and that the difficulty of coming up with any message having a given + message digest is on the order of 2^128 operations. The MD5 algorithm + has been carefully scrutinized for weaknesses. It is, however, a + relatively new algorithm and further security analysis is of course + justified, as is the case with any new proposal of this sort. + + + 5. Differences Between MD4 and MD5 + The following are the differences between MD4 and MD5: + 1. A fourth round has been added. + 2. Each step now has a unique additive constant. + 3. The function g in round 2 was changed from (XY v XZ v YZ) to + (XZ v Y not(Z)) to make g less symmetric. + 4. Each step now adds in the result of the previous step. This + promotes a faster "avalanche effect". + 5. The order in which input words are accessed in rounds 2 and + 3 is changed, to make these patterns less like each other. + 6. The shift amounts in each round have been approximately + optimized, to yield a faster "avalanche effect." The shifts in + different rounds are distinct. + + References + [1] Rivest, R., "The MD4 Message Digest Algorithm", RFC 1320, MIT and + RSA Data Security, Inc., April 1992. + [2] Rivest, R., "The MD4 message digest algorithm", in A.J. Menezes + and S.A. Vanstone, editors, Advances in Cryptology - CRYPTO '90 + Proceedings, pages 303-311, Springer-Verlag, 1991. + [3] CCITT Recommendation X.509 (1988), "The Directory - + Authentication Framework."APPENDIX A - Reference Implementation + + + The level of security discussed in this memo is considered to be + sufficient for implementing very high security hybrid digital- + signature schemes based on MD5 and a public-key cryptosystem. + Author's Address + Ronald L. Rivest Massachusetts Institute of Technology + Laboratory for Computer Science NE43-324 545 Technology Square + Cambridge, MA 02139-1986 Phone: (617) 253-5880 + EMail: rivest@theory.lcs.mit.edu + + +*****************************************************************************************/ + +#ifndef _WX_FILEH__ +class wxFile; +#endif + +class wxMD5Checksum +{ +public: + // interface functions for the RSA MD5 calculation + static wxString GetMD5(unsigned char* pBuf, unsigned int nLength); + static wxString GetMD5(wxFile& File); + static wxString GetMD5(const wxString& strFilePath); + +protected: + // constructor/destructor + wxMD5Checksum(); + virtual ~wxMD5Checksum() {}; + + // RSA MD5 implementation + void Transform(unsigned char Block[64]); + void Update(unsigned char* Input, unsigned long nInputLen); + wxString Final(); + inline unsigned long RotateLeft(unsigned long x, int n); + inline void FF( unsigned long& A, unsigned long B, unsigned long C, unsigned long D, unsigned long X, unsigned long S, unsigned long T); + inline void GG( unsigned long& A, unsigned long B, unsigned long C, unsigned long D, unsigned long X, unsigned long S, unsigned long T); + inline void HH( unsigned long& A, unsigned long B, unsigned long C, unsigned long D, unsigned long X, unsigned long S, unsigned long T); + inline void II( unsigned long& A, unsigned long B, unsigned long C, unsigned long D, unsigned long X, unsigned long S, unsigned long T); + + // utility functions + inline void DWordToByte(unsigned char* Output, unsigned long* Input, unsigned int nLength); + inline void ByteToDWord(unsigned long* Output, unsigned char* Input, unsigned int nLength); + +private: + unsigned char m_lpszBuffer[64]; // input buffer + unsigned long m_nCount[2]; // number of bits, modulo 2^64 (lsb first) + unsigned long m_lMD5[4]; // MD5 checksum +}; + +#endif + + + + + + + + diff --git a/xvaga/MD5ChecksumDefines.h b/xvaga/MD5ChecksumDefines.h new file mode 100755 index 000000000..10b7df5a6 --- /dev/null +++ b/xvaga/MD5ChecksumDefines.h @@ -0,0 +1,119 @@ +/***************************************************************************************** + +*** MD5ChecksumDefines.h : MD5 Checksum constants + +*** Developed by Langfine Ltd. +*** Released to the public domain 12/Nov/2001. +*** Please visit our website www.langfine.com + +*** Any modifications must be clearly commented to distinguish them from Langfine's +*** original source code. Please advise Langfine of useful modifications so that we +*** can make them generally available. + +*****************************************************************************************/ + + +//Magic initialization constants +#define MD5_INIT_STATE_0 0x67452301 +#define MD5_INIT_STATE_1 0xefcdab89 +#define MD5_INIT_STATE_2 0x98badcfe +#define MD5_INIT_STATE_3 0x10325476 + +//Constants for Transform routine. +#define MD5_S11 7 +#define MD5_S12 12 +#define MD5_S13 17 +#define MD5_S14 22 +#define MD5_S21 5 +#define MD5_S22 9 +#define MD5_S23 14 +#define MD5_S24 20 +#define MD5_S31 4 +#define MD5_S32 11 +#define MD5_S33 16 +#define MD5_S34 23 +#define MD5_S41 6 +#define MD5_S42 10 +#define MD5_S43 15 +#define MD5_S44 21 + +//Transformation Constants - Round 1 +#define MD5_T01 0xd76aa478 //Transformation Constant 1 +#define MD5_T02 0xe8c7b756 //Transformation Constant 2 +#define MD5_T03 0x242070db //Transformation Constant 3 +#define MD5_T04 0xc1bdceee //Transformation Constant 4 +#define MD5_T05 0xf57c0faf //Transformation Constant 5 +#define MD5_T06 0x4787c62a //Transformation Constant 6 +#define MD5_T07 0xa8304613 //Transformation Constant 7 +#define MD5_T08 0xfd469501 //Transformation Constant 8 +#define MD5_T09 0x698098d8 //Transformation Constant 9 +#define MD5_T10 0x8b44f7af //Transformation Constant 10 +#define MD5_T11 0xffff5bb1 //Transformation Constant 11 +#define MD5_T12 0x895cd7be //Transformation Constant 12 +#define MD5_T13 0x6b901122 //Transformation Constant 13 +#define MD5_T14 0xfd987193 //Transformation Constant 14 +#define MD5_T15 0xa679438e //Transformation Constant 15 +#define MD5_T16 0x49b40821 //Transformation Constant 16 + +//Transformation Constants - Round 2 +#define MD5_T17 0xf61e2562 //Transformation Constant 17 +#define MD5_T18 0xc040b340 //Transformation Constant 18 +#define MD5_T19 0x265e5a51 //Transformation Constant 19 +#define MD5_T20 0xe9b6c7aa //Transformation Constant 20 +#define MD5_T21 0xd62f105d //Transformation Constant 21 +#define MD5_T22 0x02441453 //Transformation Constant 22 +#define MD5_T23 0xd8a1e681 //Transformation Constant 23 +#define MD5_T24 0xe7d3fbc8 //Transformation Constant 24 +#define MD5_T25 0x21e1cde6 //Transformation Constant 25 +#define MD5_T26 0xc33707d6 //Transformation Constant 26 +#define MD5_T27 0xf4d50d87 //Transformation Constant 27 +#define MD5_T28 0x455a14ed //Transformation Constant 28 +#define MD5_T29 0xa9e3e905 //Transformation Constant 29 +#define MD5_T30 0xfcefa3f8 //Transformation Constant 30 +#define MD5_T31 0x676f02d9 //Transformation Constant 31 +#define MD5_T32 0x8d2a4c8a //Transformation Constant 32 + +//Transformation Constants - Round 3 +#define MD5_T33 0xfffa3942 //Transformation Constant 33 +#define MD5_T34 0x8771f681 //Transformation Constant 34 +#define MD5_T35 0x6d9d6122 //Transformation Constant 35 +#define MD5_T36 0xfde5380c //Transformation Constant 36 +#define MD5_T37 0xa4beea44 //Transformation Constant 37 +#define MD5_T38 0x4bdecfa9 //Transformation Constant 38 +#define MD5_T39 0xf6bb4b60 //Transformation Constant 39 +#define MD5_T40 0xbebfbc70 //Transformation Constant 40 +#define MD5_T41 0x289b7ec6 //Transformation Constant 41 +#define MD5_T42 0xeaa127fa //Transformation Constant 42 +#define MD5_T43 0xd4ef3085 //Transformation Constant 43 +#define MD5_T44 0x04881d05 //Transformation Constant 44 +#define MD5_T45 0xd9d4d039 //Transformation Constant 45 +#define MD5_T46 0xe6db99e5 //Transformation Constant 46 +#define MD5_T47 0x1fa27cf8 //Transformation Constant 47 +#define MD5_T48 0xc4ac5665 //Transformation Constant 48 + +//Transformation Constants - Round 4 +#define MD5_T49 0xf4292244 //Transformation Constant 49 +#define MD5_T50 0x432aff97 //Transformation Constant 50 +#define MD5_T51 0xab9423a7 //Transformation Constant 51 +#define MD5_T52 0xfc93a039 //Transformation Constant 52 +#define MD5_T53 0x655b59c3 //Transformation Constant 53 +#define MD5_T54 0x8f0ccc92 //Transformation Constant 54 +#define MD5_T55 0xffeff47d //Transformation Constant 55 +#define MD5_T56 0x85845dd1 //Transformation Constant 56 +#define MD5_T57 0x6fa87e4f //Transformation Constant 57 +#define MD5_T58 0xfe2ce6e0 //Transformation Constant 58 +#define MD5_T59 0xa3014314 //Transformation Constant 59 +#define MD5_T60 0x4e0811a1 //Transformation Constant 60 +#define MD5_T61 0xf7537e82 //Transformation Constant 61 +#define MD5_T62 0xbd3af235 //Transformation Constant 62 +#define MD5_T63 0x2ad7d2bb //Transformation Constant 63 +#define MD5_T64 0xeb86d391 //Transformation Constant 64 + + +//Null data (except for first unsigned char) used to finalise the checksum calculation +static unsigned char PADDING[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + diff --git a/xvaga/email.cpp b/xvaga/email.cpp new file mode 100755 index 000000000..2cb46a697 --- /dev/null +++ b/xvaga/email.cpp @@ -0,0 +1,120 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: email.h +// Purpose: wxEmail: portable email client class +// Author: Julian Smart +// Modified by: +// Created: 2001-08-21 +// RCS-ID: $Id: email.cpp,v 1.2 2008-03-11 15:43:15 alex Exp $ +// Copyright: (c) Julian Smart +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// +#include "wxinc.h" + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/string.h" +#include "email.h" + +#ifdef __WXMSW__ +#include "smapi.h" +#endif + +#ifdef __UNIX__ +#include "wx/filefn.h" +#include "wx/timer.h" +#include "wx/wfstream.h" +#include "stdlib.h" +#include "unistd.h" +#endif + +// Send a message. +// Specify profile, if empty use MAPI default profile +#ifdef __WXMSW__ +bool wxEmail::Send(wxMailMessage& message, const wxString& profileName, const wxString& WXUNUSED(sendMail)) +{ + wxASSERT (message.m_to.GetCount() > 0) ; + + wxString profile(profileName); + + wxMapiSession session; + + if (!session.MapiInstalled()) + return FALSE; + if (!session.Logon(profile)) + return FALSE; + + return session.Send(message, true); +} +#elif defined(__UNIX__) +bool +wxEmail::Send(wxMailMessage& message, + const wxString& profileName, + const wxString& sendMail) +{ + wxASSERT_MSG( !message.m_to.IsEmpty(), _T("no recipients to send mail to") ) ; + + + // The 'from' field is optionally supplied by the app; it's not needed + // by MAPI, and on Unix, will be guessed if not supplied. + wxString from = message.m_from; + if ( from.empty() ) + { + from = wxGetEmailAddress(); + } + + wxString msg; + msg << wxT("To: "); + + const size_t rcptCount = message.m_to.GetCount(); + for (size_t rcpt = 0; rcpt < rcptCount; rcpt++) + { + if ( rcpt ) + msg << wxT(", "); + msg << message.m_to[rcpt]; + } + + msg << wxT("\nFrom: ") << from << wxT("\nSubject: ") << message.m_subject; + msg << wxT("\n\n") << message.m_body; + + wxString filename; + filename.Printf(wxT("/tmp/msg-%ld-%ld-%ld.txt"), (long) getpid(), wxGetLocalTime(), + (long) rand()); + + { + wxFileOutputStream stream(filename); + if (stream.Ok()) + { + stream.Write(msg, msg.Length()); + } + else + { + return FALSE ; + } + } + + // TODO search for a suitable sendmail if sendMail is empty + wxString sendmail(sendMail); + + wxString cmd; + cmd << sendmail << wxT(" < ") << filename; + + // TODO: check return code + wxSystem(cmd.c_str()); + + wxRemoveFile(filename); + + return TRUE; +} +#else +#error Send not yet implemented for this platform. +#endif + diff --git a/xvaga/email.h b/xvaga/email.h new file mode 100755 index 000000000..d41f62f75 --- /dev/null +++ b/xvaga/email.h @@ -0,0 +1,40 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: email.h +// Purpose: wxEmail: portable email client class +// Author: Julian Smart +// Modified by: +// Created: 2001-08-21 +// RCS-ID: $Id: email.h,v 1.2 2008-03-11 15:43:15 alex Exp $ +// Copyright: (c) Julian Smart +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_EMAIL_H_ +#define _WX_EMAIL_H_ + +#include "msg.h" + +/* + * wxEmail + * Miscellaneous email functions + */ + +class wxEmail +{ +public: +//// Ctor/dtor + wxEmail() {}; + +//// Operations + + // Send a message. + // Specify profile, or leave it to wxWidgets to find the current user name + static bool Send(wxMailMessage& message, const wxString& profileName = wxEmptyString, + const wxString& sendMail = wxT("/usr/sbin/sendmail -t")); + +protected: +}; + + +#endif //_WX_EMAIL_H_ + diff --git a/xvaga/msg.h b/xvaga/msg.h new file mode 100755 index 000000000..240edbb42 --- /dev/null +++ b/xvaga/msg.h @@ -0,0 +1,69 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: msg.h +// Purpose: wxMailMessage +// Author: Julian Smart +// Modified by: +// Created: 2001-08-21 +// RCS-ID: $Id: msg.h,v 1.2 2008-03-11 15:43:15 alex Exp $ +// Copyright: (c) Julian Smart +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_MSG_H_ +#define _WX_MSG_H_ + +#include "wxinc.h" + +/* + * wxMailMessage + * Encapsulates an email message + */ + +class wxMailMessage +{ +public: + + // A common usage + wxMailMessage(const wxString& subject, const wxString& to, + const wxString& body, const wxString& from = wxEmptyString, + const wxString& attachment = wxEmptyString, + const wxString& attachmentTitle = wxEmptyString) + { + m_to.Add(to); + m_subject = subject; + m_body = body; + m_from = from; + if (!attachment.IsEmpty()) + { + m_attachments.Add(attachment); + m_attachmentTitles.Add(attachmentTitle); + } + } + + wxMailMessage() {}; + +//// Accessors + + void AddTo(const wxString& to) { m_to.Add(to); } + void AddCc(const wxString& cc) { m_cc.Add(cc); } + void AddBcc(const wxString& bcc) { m_bcc.Add(bcc); } + void AddAttachment(const wxString& attach, const wxString& title = wxEmptyString) + { m_attachments.Add(attach); m_attachmentTitles.Add(title); } + + void SetSubject(const wxString& subject) { m_subject = subject; } + void SetBody(const wxString& body) { m_body = body; } + void SetFrom(const wxString& from) { m_from = from; } + +public: + wxArrayString m_to; //The To: Recipients + wxString m_from; //The From: email address (optional) + wxArrayString m_cc; //The CC: Recipients + wxArrayString m_bcc; //The BCC Recipients + wxString m_subject; //The Subject of the message + wxString m_body; //The Body of the message + wxArrayString m_attachments; //Files to attach to the email + wxArrayString m_attachmentTitles; //Titles to use for the email file attachments +}; + +#endif // _WX_MSG_H_ + diff --git a/xvaga/smapi.cpp b/xvaga/smapi.cpp new file mode 100755 index 000000000..3902a66eb --- /dev/null +++ b/xvaga/smapi.cpp @@ -0,0 +1,498 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: smapi.cpp +// Purpose: Simple MAPI classes +// Author: PJ Naughter +// Modified by: Julian Smart +// Created: 2001-08-21 +// RCS-ID: $Id: smapi.cpp,v 1.2 2008-03-11 15:43:15 alex Exp $ +// Copyright: (c) PJ Naughter +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// +#include "wxinc.h" + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifdef __WXMSW__ + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/string.h" +#include "wx/msw/private.h" + +// mapi.h in Cygwin's include directory isn't a full implementation and is +// not sufficient for this lib. However recent versions of Cygwin also +// have another mapi.h in include/w32api which can be used. +// +#ifdef __CYGWIN__ +#include +#else +#include +#endif + +#include "smapi.h" + +class wxMapiData +{ +public: + wxMapiData() + { + m_hSession = 0; + m_nLastError = 0; + m_hMapi = NULL; + m_lpfnMAPILogon = NULL; + m_lpfnMAPILogoff = NULL; + m_lpfnMAPISendMail = NULL; + m_lpfnMAPIResolveName = NULL; + m_lpfnMAPIFreeBuffer = NULL; + } + + //Data + LHANDLE m_hSession; //Mapi Session handle + long m_nLastError; //Last Mapi error value + HINSTANCE m_hMapi; //Instance handle of the MAPI dll + LPMAPILOGON m_lpfnMAPILogon; //MAPILogon function pointer + LPMAPILOGOFF m_lpfnMAPILogoff; //MAPILogoff function pointer + LPMAPISENDMAIL m_lpfnMAPISendMail; //MAPISendMail function pointer + LPMAPIRESOLVENAME m_lpfnMAPIResolveName; //MAPIResolveName function pointer + LPMAPIFREEBUFFER m_lpfnMAPIFreeBuffer; //MAPIFreeBuffer function pointer +}; + + +////////////////////////////////// Implementation ///////////////////////////// + +wxMapiSession::wxMapiSession() +{ + m_data = new wxMapiData; + + Initialise(); +} + +wxMapiSession::~wxMapiSession() +{ + //Logoff if logged on + Logoff(); + + //Unload the MAPI dll + Deinitialise(); + + delete m_data; +} + +void wxMapiSession::Initialise() +{ + //First make sure the "WIN.INI" entry for MAPI is present aswell + //as the MAPI32 dll being present on the system + bool bMapiInstalled = (GetProfileInt(_T("MAIL"), _T("MAPI"), 0) != 0) && + (SearchPath(NULL, _T("MAPI32.DLL"), NULL, 0, NULL, NULL) != 0); + + if (bMapiInstalled) + { + //Load up the MAPI dll and get the function pointers we are interested in + m_data->m_hMapi = ::LoadLibrary(_T("MAPI32.DLL")); + if (m_data->m_hMapi) + { + m_data->m_lpfnMAPILogon = (LPMAPILOGON) GetProcAddress(m_data->m_hMapi, "MAPILogon"); + m_data->m_lpfnMAPILogoff = (LPMAPILOGOFF) GetProcAddress(m_data->m_hMapi, "MAPILogoff"); + m_data->m_lpfnMAPISendMail = (LPMAPISENDMAIL) GetProcAddress(m_data->m_hMapi, "MAPISendMail"); + m_data->m_lpfnMAPIResolveName = (LPMAPIRESOLVENAME) GetProcAddress(m_data->m_hMapi, "MAPIResolveName"); + m_data->m_lpfnMAPIFreeBuffer = (LPMAPIFREEBUFFER) GetProcAddress(m_data->m_hMapi, "MAPIFreeBuffer"); + + //If any of the functions are not installed then fail the load + if (m_data->m_lpfnMAPILogon == NULL || + m_data->m_lpfnMAPILogoff == NULL || + m_data->m_lpfnMAPISendMail == NULL || + m_data->m_lpfnMAPIResolveName == NULL || + m_data->m_lpfnMAPIFreeBuffer == NULL) + { + wxLogDebug(_T("Failed to get one of the functions pointer in MAPI32.DLL\n")); + Deinitialise(); + } + } + } + else + wxLogDebug(_T("Mapi is not installed on this computer\n")); +} + +void wxMapiSession::Deinitialise() +{ + if (m_data->m_hMapi) + { + //Unload the MAPI dll and reset the function pointers to NULL + FreeLibrary(m_data->m_hMapi); + m_data->m_hMapi = NULL; + m_data->m_lpfnMAPILogon = NULL; + m_data->m_lpfnMAPILogoff = NULL; + m_data->m_lpfnMAPISendMail = NULL; + m_data->m_lpfnMAPIResolveName = NULL; + m_data->m_lpfnMAPIFreeBuffer = NULL; + } +} + +bool wxMapiSession::Logon(const wxString& sProfileName, const wxString& sPassword, wxWindow* pParentWnd) +{ + wxASSERT(MapiInstalled()); //MAPI must be installed + wxASSERT(m_data->m_lpfnMAPILogon); //Function pointer must be valid + + //Initialise the function return value + bool bSuccess = FALSE; + + //Just in case we are already logged in + Logoff(); + + //Setup the ascii versions of the profile name and password + int nProfileLength = sProfileName.Length(); + + LPSTR pszProfileName = NULL; + LPSTR pszPassword = NULL; + wxCharBuffer cbProfile(1),cbPassword(1); + if (nProfileLength) + { +#ifndef UNICODE + pszProfileName = (LPSTR) sProfileName.c_str(); + pszPassword = (LPSTR) sPassword.c_str(); +#else + cbProfile = sProfileName.mb_str(); + cbPassword = sPassword.mb_str(); + pszProfileName = cbProfile.data(); + pszPassword = cbPassword.data(); +#endif + } + + //Setup the flags & UIParam parameters used in the MapiLogon call + FLAGS flags = 0; + ULONG nUIParam = 0; + if (nProfileLength == 0) + { + //No profile name given, then we must interactively request a profile name + if (pParentWnd) + { + nUIParam = (ULONG) (HWND) pParentWnd->GetHWND(); + flags |= MAPI_LOGON_UI; + } + else + { + //No window given, just use the main window of the app as the parent window + if (wxTheApp->GetTopWindow()) + { + nUIParam = (ULONG) (HWND) wxTheApp->GetTopWindow()->GetHWND(); + flags |= MAPI_LOGON_UI; + } + } + } + + //First try to acquire a new MAPI session using the supplied settings using the MAPILogon functio + ULONG nError = m_data->m_lpfnMAPILogon(nUIParam, pszProfileName, pszPassword, flags | MAPI_NEW_SESSION, 0, &m_data->m_hSession); + if (nError != SUCCESS_SUCCESS && nError != MAPI_E_USER_ABORT) + { + //Failed to create a create mapi session, try to acquire a shared mapi session + wxLogDebug(_T("Failed to logon to MAPI using a new session, trying to acquire a shared one\n")); + nError = m_data->m_lpfnMAPILogon(nUIParam, NULL, NULL, 0, 0, &m_data->m_hSession); + if (nError == SUCCESS_SUCCESS) + { + m_data->m_nLastError = SUCCESS_SUCCESS; + bSuccess = TRUE; + } + else + { + wxLogDebug(_T("Failed to logon to MAPI using a shared session, Error:%ld\n"), nError); + m_data->m_nLastError = nError; + } + } + else if (nError == SUCCESS_SUCCESS) + { + m_data->m_nLastError = SUCCESS_SUCCESS; + bSuccess = TRUE; + } + + return bSuccess; +} + +bool wxMapiSession::LoggedOn() const +{ + return (m_data->m_hSession != 0); +} + +bool wxMapiSession::MapiInstalled() const +{ + return (m_data->m_hMapi != NULL); +} + +bool wxMapiSession::Logoff() +{ + wxASSERT(MapiInstalled()); //MAPI must be installed + wxASSERT(m_data->m_lpfnMAPILogoff); //Function pointer must be valid + + //Initialise the function return value + bool bSuccess = FALSE; + + if (m_data->m_hSession) + { + //Call the MAPILogoff function + ULONG nError = m_data->m_lpfnMAPILogoff(m_data->m_hSession, 0, 0, 0); + if (nError != SUCCESS_SUCCESS) + { + wxLogDebug(_T("Failed in call to MapiLogoff, Error:%ld"), nError); + m_data->m_nLastError = nError; + bSuccess = TRUE; + } + else + { + m_data->m_nLastError = SUCCESS_SUCCESS; + bSuccess = TRUE; + } + m_data->m_hSession = 0; + } + + return bSuccess; +} + +bool wxMapiSession::Resolve(const wxString& sName, void* lppRecip1) +{ + lpMapiRecipDesc* lppRecip = (lpMapiRecipDesc*) lppRecip1; + + wxASSERT(MapiInstalled()); //MAPI must be installed + wxASSERT(m_data->m_lpfnMAPIResolveName); //Function pointer must be valid + wxASSERT(LoggedOn()); //Must be logged on to MAPI + wxASSERT(m_data->m_hSession); //MAPI session handle must be valid + + //Call the MAPIResolveName function +#ifndef UNICODE + LPSTR lpszAsciiName = (LPSTR) sName.c_str(); +#else + wxCharBuffer cbName(1); + cbName = sName.mb_str(); + LPSTR lpszAsciiName = cbName.data(); +#endif + ULONG nError = m_data->m_lpfnMAPIResolveName(m_data->m_hSession, 0, lpszAsciiName, 0, 0, lppRecip); + if (nError != SUCCESS_SUCCESS) + { + wxLogDebug(_T("Failed to resolve the name: %s, Error:%ld\n"), + sName.c_str(), nError); + m_data->m_nLastError = nError; + } + + return (nError == SUCCESS_SUCCESS); +} + +bool wxMapiSession::Send(wxMailMessage& message, bool hide_ui) +{ + wxASSERT(MapiInstalled()); //MAPI must be installed + wxASSERT(m_data->m_lpfnMAPISendMail); //Function pointer must be valid + wxASSERT(m_data->m_lpfnMAPIFreeBuffer); //Function pointer must be valid + wxASSERT(LoggedOn()); //Must be logged on to MAPI + wxASSERT(m_data->m_hSession); //MAPI session handle must be valid + + //Initialise the function return value + bool bSuccess = FALSE; + + //Create the MapiMessage structure to match the message parameter send into us + MapiMessage mapiMessage; + ZeroMemory(&mapiMessage, sizeof(mapiMessage)); +#ifndef UNICODE + mapiMessage.lpszSubject = (LPSTR) message.m_subject.c_str(); + mapiMessage.lpszNoteText = (LPSTR) message.m_body.c_str(); +#else + wxCharBuffer cbSubject(1),cbBody(1),cbOriginator(1); + cbSubject = message.m_subject.mb_str(); + cbBody = message.m_body.mb_str(); + mapiMessage.lpszSubject = cbSubject.data(); + mapiMessage.lpszNoteText = cbBody.data(); +#endif + mapiMessage.nRecipCount = message.m_to.GetCount() + message.m_cc.GetCount() + message.m_bcc.GetCount(); + wxASSERT(mapiMessage.nRecipCount); //Must have at least 1 recipient! + + //Allocate the recipients array + mapiMessage.lpRecips = new MapiRecipDesc[mapiMessage.nRecipCount]; + + // If we have a 'From' field, use it + if (!message.m_from.IsEmpty()) + { + mapiMessage.lpOriginator = new MapiRecipDesc; + ZeroMemory(mapiMessage.lpOriginator, sizeof(MapiRecipDesc)); + + mapiMessage.lpOriginator->ulRecipClass = MAPI_ORIG; + // TODO Do we have to call Resolve? +#ifndef UNICODE + mapiMessage.lpOriginator->lpszName = (LPSTR) message.m_from.c_str(); +#else + cbOriginator = message.m_from.mb_str(); + mapiMessage.lpOriginator->lpszName = cbOriginator.data(); +#endif + } + + //Setup the "To" recipients + int nRecipIndex = 0; + int nToSize = message.m_to.GetCount(); + int i; + for (i=0; ilpszName,*wxConvCurrent); + + //Don't forget to free up the memory MAPI allocated for us + m_data->m_lpfnMAPIFreeBuffer(lpTempRecip); + } +#ifndef UNICODE + recip.lpszName = (LPSTR) sName.c_str(); +#else + recip.lpszName = sName.mb_str().release(); +#endif + + ++nRecipIndex; + } + + //Setup the "CC" recipients + int nCCSize = message.m_cc.GetCount(); + for (i=0; ilpszName,*wxConvCurrent); + + //Don't forget to free up the memory MAPI allocated for us + m_data->m_lpfnMAPIFreeBuffer(lpTempRecip); + } +#ifndef UNICODE + recip.lpszName = (LPSTR) sName.c_str(); +#else + recip.lpszName = sName.mb_str().release(); +#endif + + ++nRecipIndex; + } + + //Setup the "BCC" recipients + int nBCCSize = message.m_bcc.GetCount(); + for (i=0; ilpszName,wxConvCurrent); + + //Don't forget to free up the memory MAPI allocated for us + m_data->m_lpfnMAPIFreeBuffer(lpTempRecip); + } +#ifndef UNICODE + recip.lpszName = (LPSTR) sName.c_str(); +#else + recip.lpszName = sName.mb_str().release(); +#endif + + ++nRecipIndex; + } + + //Setup the attachments + int nAttachmentSize = message.m_attachments.GetCount(); + int nTitleSize = message.m_attachmentTitles.GetCount(); + if (nTitleSize) + { + wxASSERT(nTitleSize == nAttachmentSize); //If you are going to set the attachment titles then you must set + //the attachment title for each attachment + } + if (nAttachmentSize) + { + mapiMessage.nFileCount = nAttachmentSize; + mapiMessage.lpFiles = new MapiFileDesc[nAttachmentSize]; + for (i=0; im_lpfnMAPISendMail(m_data->m_hSession, 0, &mapiMessage, hide_ui ? 0 : MAPI_DIALOG, 0); + if (nError == SUCCESS_SUCCESS) + { + bSuccess = TRUE; + m_data->m_nLastError = SUCCESS_SUCCESS; + } + else + { + wxLogDebug(_T("Failed to send mail message, Error:%ld\n"), nError); + m_data->m_nLastError = nError; + } + + //Tidy up the Attachements + if (nAttachmentSize) + { +#ifdef UNICODE + for (i = 0;i < nAttachmentSize;i++) + { + free(mapiMessage.lpFiles[i].lpszPathName); + free(mapiMessage.lpFiles[i].lpszFileName); + } +#endif + delete [] mapiMessage.lpFiles; + } + + //Free up the Recipients and Originator memory +#ifdef UNICODE + for (i = 0;i < nRecipIndex;i++) + free(mapiMessage.lpRecips[i].lpszName); +#endif + delete [] mapiMessage.lpRecips; + + delete mapiMessage.lpOriginator; + + return bSuccess; +} + +long wxMapiSession::GetLastError() const +{ + return m_data->m_nLastError; +} + +#endif // __WXMSW__ diff --git a/xvaga/smapi.h b/xvaga/smapi.h new file mode 100755 index 000000000..6dbd8b977 --- /dev/null +++ b/xvaga/smapi.h @@ -0,0 +1,52 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: smapi.h +// Purpose: Simple MAPI classes +// Author: PJ Naughter +// Modified by: Julian Smart +// Created: 2001-08-21 +// RCS-ID: $Id: smapi.h,v 1.2 2008-03-11 15:43:15 alex Exp $ +// Copyright: (c) PJ Naughter +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_SMAPI_H_ +#define _WX_SMAPI_H_ + +#include "msg.h" + +class wxMapiData; + +//The class which encapsulates the MAPI connection +class wxMapiSession +{ +public: + //Constructors / Destructors + wxMapiSession(); + ~wxMapiSession(); + + //Logon / Logoff Methods + bool Logon(const wxString& sProfileName, const wxString& sPassword = wxEmptyString, wxWindow* pParentWnd = NULL); + bool LoggedOn() const; + bool Logoff(); + + //Send a message + bool Send(wxMailMessage& message, bool hide_ui); + + //General MAPI support + bool MapiInstalled() const; + + //Error Handling + long GetLastError() const; + +protected: + //Methods + void Initialise(); + void Deinitialise(); + bool Resolve(const wxString& sName, void* lppRecip1); + + wxMapiData* m_data; + +}; + + +#endif //_WX_SMAPI_H_ diff --git a/xvaga/xvaga.cpp b/xvaga/xvaga.cpp index 1e333b8cf..588d4b4b0 100755 --- a/xvaga/xvaga.cpp +++ b/xvaga/xvaga.cpp @@ -2307,7 +2307,7 @@ COLOR xvt_image_get_clut(XVT_IMAGE image, short index) const wxPalette& pal = bmp.GetPalette(); unsigned char r, g, b; pal.GetRGB(index, &r, &g, &b); - return MAKE_COLOR(r, g, b); + return XVT_MAKE_COLOR(r, g, b); } } return COLOR_BLACK; @@ -2359,7 +2359,7 @@ COLOR xvt_image_get_pixel(XVT_IMAGE image, short x, short y) int r = bmp.GetRed(x, y); int g = bmp.GetGreen(x, y); int b = bmp.GetBlue(x, y); - return MAKE_COLOR(r, g, b); + return XVT_MAKE_COLOR(r, g, b); } XVT_IMAGE xvt_image_read(const char* filenamep) @@ -3918,9 +3918,10 @@ RCT* xvt_vobj_get_outer_rect(WINDOW win, RCT *rctp) XVT_ASSERT(rctp != NULL); CAST_WIN(win, w); const wxRect rct = w.GetRect(); - rctp->left = rct.x; rctp->top = rct.y; - rctp->right = rct.x + rct.width; - rctp->bottom = rct.y + rct.height; + rctp->left = rct.x; + rctp->top = rct.y; + rctp->right = rct.GetRight(); + rctp->bottom = rct.GetBottom(); return rctp; } diff --git a/xvaga/xvt.h b/xvaga/xvt.h index 1aa68bd24..b2072a87e 100755 --- a/xvaga/xvt.h +++ b/xvaga/xvt.h @@ -187,6 +187,7 @@ XVTDLL BOOLEAN xvt_fsys_file_exists(const char *pathname); XVTDLL int xvt_fsys_get_campo_stp_value(const char* name, char* value, int valsize); XVTDLL const char* xvt_fsys_get_campo_ini(); XVTDLL long xvt_fsys_file_attr(const char* pathname, long attr); +XVTDLL BOOLEAN xvt_fsys_file_md5(const char* path, char* outstr32); XVTDLL void xvt_help_close_helpfile(XVT_HELP_INFO hi); XVTDLL XVT_HELP_INFO xvt_help_open_helpfile(FILE_SPEC *fs, unsigned long flags); @@ -322,6 +323,8 @@ XVTDLL BOOLEAN xvt_str_match(const char* str, const char* pat, BOOLEAN case_sens XVTDLL double xvt_str_fuzzy_compare (const char* s1, const char* s2); XVTDLL void xvt_str_make_upper(char* str); XVTDLL void xvt_str_make_lower(char* str); +XVTDLL BOOLEAN xvt_str_md5(const char* instr, char* outstr32); + XVTDLL XVT_TREEVIEW_NODE xvt_treeview_add_child_node(WINDOW win, XVT_TREEVIEW_NODE parent, XVT_TREEVIEW_NODE_TYPE type, diff --git a/xvaga/xvtextra.cpp b/xvaga/xvtextra.cpp index 50b8f6739..d3bdffc0f 100755 --- a/xvaga/xvtextra.cpp +++ b/xvaga/xvtextra.cpp @@ -1168,3 +1168,33 @@ const char* xvt_fsys_get_campo_ini() } return prawin; } + +/////////////////////////////////////////////////////////// +// Gestione MD5 +/////////////////////////////////////////////////////////// + +#include "MD5Checksum.h" + +BOOLEAN xvt_str_md5(const char* instr, char* outstr) +{ + wxASSERT(outstr != NULL); + BOOLEAN ok = instr && *instr && outstr; + if (ok) + { + strcpy(outstr, wxMD5Checksum::GetMD5((unsigned char*)instr, strlen(instr))); + ok = *outstr != '\0'; + } + return ok; +} + +BOOLEAN xvt_fsys_file_md5(const char* path, char* outstr) +{ + wxASSERT(outstr != NULL); + BOOLEAN ok = path && *path && outstr; + if (ok) + { + strcpy(outstr, wxMD5Checksum::GetMD5(wxString(path))); + ok = *outstr != '\0'; + } + return ok; +} diff --git a/xvaga/xvtmail.cpp b/xvaga/xvtmail.cpp index 8d2cba6e3..32e457d99 100755 --- a/xvaga/xvtmail.cpp +++ b/xvaga/xvtmail.cpp @@ -1,8 +1,38 @@ +#include "wxinc.h" #include "xvt.h" +#include +#include "msg.h" +#include "email.h" BOOLEAN xvt_mail_send(const char* to, const char* cc, const char* ccn, const char* subject, const char* msg, const char* attach, BOOLEAN ui) { - return FALSE; + xvt_fsys_save_dir(); + wxStringTokenizer tokTo(to, _T(";")); + wxStringTokenizer tokAttach(attach, _T(";")); + + wxMailMessage Msg(subject, tokTo.GetNextToken(), msg, wxEmptyString, tokAttach.GetNextToken()); + + while (tokTo.HasMoreTokens()) + Msg.AddTo(tokTo.GetNextToken()); + + while (tokAttach.HasMoreTokens()) + Msg.AddAttachment(tokAttach.GetNextToken()); + + wxStringTokenizer Tok(cc, _T(";")); + + while (Tok.HasMoreTokens()) + Msg.AddCc(Tok.GetNextToken()); + + Tok.SetString(ccn, _T(";")); + + while (Tok.HasMoreTokens()) + Msg.AddBcc(Tok.GetNextToken()); + + wxEmail Mail; + + BOOLEAN ok = Mail.Send(Msg); + xvt_fsys_restore_dir(); + return ok; } \ No newline at end of file