#include #include #include #include #include #include "../cg/cg2101.h" #include "../cg/cg2103.h" #include "../cg/cgsaldac.h" #include "../mg/movmag.h" #include "../mg/rmovmag.h" #include "halib.h" #include "ha1250.h" #include "ha1300a.h" #include "ha1301a.h" //funzione di ordinamento del file di upload una volta caricato in memoria static TToken_string tipi_record("SU|VC|TF|RF|SI|BR|RC"); int ordina_upload(const TObject** o1, const TObject** o2) { const TString& s1 = *(TString*)*o1; const TString& s2 = *(TString*)*o2; //ordinatore dei record Testata e Riga fattura if (s1[1] == 'F' && s2[1] == 'F') { TToken_string k[2]; for (int i = 0; i < 2; i++) { const TString& rec = i == 0 ? s1 : s2; TToken_string& key = k[i]; if (rec[0] == 'T') { key.add(rec.mid(14,2)); //anno key.add(rec.mid(16,1)); //tipodoc key.add(rec.mid(5,5)); //numdoc } else { key.add(rec.mid(14,2)); //anno key.add(rec.mid(28,1)); //tipodoc key.add(rec.mid(5,5)); //numdoc key.add(rec.mid(29,5)); //codart } } return k[0].compare(k[1]); } const int pos1 = tipi_record.get_pos(s1.left(2)); const int pos2 = tipi_record.get_pos(s2.left(2)); if (pos1 != pos2) return pos1 - pos2; return s1.compare(s2); } //------------------------------------------------------------ // Hardy_upload_recordset: serve per l'INPUT //------------------------------------------------------------ class THardy_upload_recordset : public THardy_recordset { protected: virtual TRecnotype new_rec(const char* trc); public: THardy_upload_recordset(const TFilename& filename); }; ///////////////////////////////////////////////////////////// // Recordset specifici per i dati da trasferire INPUT ///////////////////////////////////////////////////////////// TRecnotype THardy_upload_recordset::new_rec(const char* trc) { if (trc && *trc > ' ') { TString rec; rec << trc << "\r\n"; return TText_recordset::new_rec(rec); } return -1; } //questo invece è il metodo magico che vale per il caricamento da file esterno THardy_upload_recordset::THardy_upload_recordset(const TFilename& filename) : THardy_recordset(256) { TFilename cazzone; //as400 con lunghezza 256 e chiave lunga 2 (a partire dall'inizio): è il tipo record parse_query("AS400(256,2)", cazzone); //Tipo record SU //-------------- add_trc_field("SU", "TipoRecord", T_X, 1, 2); //x add_trc_field("SU", "CodiceTerminale", T_N, 3, 3); //x add_trc_field("SU", "CodiceAgente", T_N, 6, 3); //x add_trc_field("SU", "NonUsato", T_X, 9, 6); add_trc_field("SU", "Targa", T_X, 15, 8); add_trc_field("SU", "nDDT", T_N, 23, 5); add_trc_field("SU", "nFATT", T_N, 28, 5); add_trc_field("SU", "nBOLLA", T_N, 33, 5); add_trc_field("SU", "NomeAgente", T_X, 38, 30); //x //Tipo record TF //-------------- add_trc_field("TF", "TipoRecord", T_X, 1, 2); //x add_trc_field("TF", "CodiceTerminale", T_N, 3, 3); //x add_trc_field("TF", DOC_NDOC, T_N, 6, 5); //x add_trc_field("TF", DOC_DATADOC, T_X, 11, 6); //x add_trc_field("TF", DOC_TIPODOC, T_X, 17, 1); //x add_trc_field("TF", DOC_CODCF, T_X, 18, 6); //x add_trc_field("TF", DOC_CODCFFATT, T_X, 24, 6); //x add_trc_field("TF", "ImponibileLordo", T_Nv2N, 30, 8); // campi seguenti da righe doc add_trc_field("TF", "ScontoFattura", T_2Nv2N,38, 4); add_trc_field("TF", "ImponibileDoc", T_Nv2N, 42, 8); add_trc_field("TF", "TotaleDoc", T_Nv2N, 50, 8); add_trc_field("TF", "ScontoTotale", T_Nv2N, 58, 8); add_trc_field("TF", "ImponibileOmaggi", T_Nv2N, 66, 8); add_trc_field("TF", "ImponibileSost", T_Nv2N, 74, 8); add_trc_field("TF", "Incasso", T_Nv2N, 82, 8); //forse IMPPAGATO ? add_trc_field("TF", DOC_CODPAG, T_X, 90, 2); //x add_trc_field("TF", DOC_DATAPART, T_X, 92, 6); //x add_trc_field("TF", "Iva1", T_N, 98, 2); //anche questi da righe doc add_trc_field("TF", "Imponibile1", T_Nv2N, 100,8); add_trc_field("TF", "Imposta1", T_Nv2N, 108,7); add_trc_field("TF", "Iva2", T_N, 115,2); add_trc_field("TF", "Imponibile2", T_Nv2N, 117,8); add_trc_field("TF", "Imposta2", T_Nv2N, 125,7); add_trc_field("TF", "Iva3", T_N, 132,2); add_trc_field("TF", "Imponibile3", T_Nv2N, 134,8); add_trc_field("TF", "Imposta3", T_Nv2N, 142,7); add_trc_field("TF", "Iva4", T_N, 149,2); add_trc_field("TF", "Imponibile4", T_Nv2N, 151,8); add_trc_field("TF", "Imposta4", T_Nv2N, 159,7); add_trc_field("TF", "CodcliGiro3", T_X, 166,6); add_trc_field("TF", "IvaOmag1", T_N, 172,2); add_trc_field("TF", "ImponibileOmag1", T_Nv2N, 174,6); add_trc_field("TF", "ImpostaOmag1", T_Nv2N, 180,5); add_trc_field("TF", "IvaOmag2", T_N, 185,2); add_trc_field("TF", "ImponibileOmag2", T_Nv2N, 187,6); add_trc_field("TF", "ImpostaOmag2", T_Nv2N, 193,5); add_trc_field("TF", "DataEmissione", T_X, 198,6); add_trc_field("TF", "PagamentoCarta", T_X, 204,1); //Tipo record RF //-------------- add_trc_field("RF", "TipoRecord", T_X, 1, 2); //x add_trc_field("RF", "CodiceTerminale", T_N, 3, 3); //x add_trc_field("RF", RDOC_NDOC, T_N, 6, 5); //x add_trc_field("RF", DOC_DATADOC, T_X, 11, 6); //x testata add_trc_field("RF", DOC_CODCF, T_X, 17, 6); //x testata add_trc_field("RF", DOC_CODCFFATT, T_X, 23, 6); //x testata add_trc_field("RF", DOC_TIPODOC, T_X, 29, 1); //x testata add_trc_field("RF", RDOC_CODART, T_X, 30, 5); //x add_trc_field("RF", "TipoCessione", T_X, 35, 1); add_trc_field("RF", "Qta[int]", T_N, 36, 5); //x add_trc_field("RF", "Qta[dec]", T_N, 41, 2); //x add_trc_field("RF", "Sconto1", T_2Nv2N,43, 4); add_trc_field("RF", "Sconto2", T_2Nv2N,47, 4); add_trc_field("RF", "Sconto3", T_2Nv2N,51, 4); add_trc_field("RF", "ScontoLibero", T_2Nv2N,55, 4); add_trc_field("RF", RDOC_PREZZO, T_Nv3N, 59, 7); //x forse PREZZOL ? add_trc_field("RF", "TotaleRiga", T_Nv3N, 66, 8); add_trc_field("RF", "TotaleSconto", T_Nv3N, 74, 8); add_trc_field("RF", "AliquotaIva", T_N, 82, 2); //noi abbiamo il codice add_trc_field("RF", RDOC_UMQTA, T_X, 84, 2); //x add_trc_field("RF", "PrezzoScontato", T_Nv3N, 86, 7); add_trc_field("RF", "Fascia", T_X, 93, 1); add_trc_field("RF", "ScontoFascia", T_2N, 94, 2); add_trc_field("RF", "NonUsato", T_N, 96, 2); add_trc_field("RF", "CodcliGiro3", T_X, 98, 6); add_trc_field("RF", "CodiceLotto", T_X, 104,10); //noi lo leghiamo all'articolo //Tipo record SI //-------------- add_trc_field("SI", "TipoRecord", T_X, 1, 2); //x add_trc_field("SI", "CodiceTerminale", T_N, 3, 3); //x add_trc_field("SI", "CodiceCliente", T_X, 6, 6); add_trc_field("SI", "NumeroFattura", T_X, 12, 12); add_trc_field("SI", "DataFattura", T_X, 24, 6); add_trc_field("SI", "NonUsato", T_N, 30, 9); add_trc_field("SI", "ImportoIncassato", T_Nv2N, 39, 9); add_trc_field("SI", "DataIncasso", T_X, 48, 6); add_trc_field("SI", "Partita", T_X, 54, 15); add_trc_field("SI", "TipoDocumento", T_X, 69, 1); add_trc_field("SI", "DataEmissione", T_X, 70, 6); add_trc_field("SI", "PagamentoCarta", T_X, 76, 1); //Tipo record BR //-------------- add_trc_field("BR", "TipoRecord", T_X, 1, 2); //x add_trc_field("BR", "CodiceTerminale", T_N, 3, 3); //x add_trc_field("BR", "NumeroRiga", T_N, 6, 3); add_trc_field("BR", "NumeroDoc", T_N, 9, 5); add_trc_field("BR", "DataMov", T_X, 14, 6); add_trc_field("BR", "CodiceArticolo", T_X, 20, 5); add_trc_field("BR", "Qta[int]", T_N, 25, 5); add_trc_field("BR", "Qta[dec]", T_N, 30, 2); add_trc_field("BR", "Mittente", T_N, 32, 3); add_trc_field("BR", "Destinatario", T_N, 35, 3); add_trc_field("BR", "CausaleMov", T_N, 38, 2); add_trc_field("BR", "CodiceLotto", T_X, 40, 10); //Tipo record VC //-------------- add_trc_field("VC", "TipoRecord", T_X, 1, 2); //x add_trc_field("VC", "CodiceTerminale", T_N, 3, 3); //x add_trc_field("VC", "CodiceCliente", T_X, 6, 6); //x add_trc_field("VC", "RagioneSociale", T_X, 12, 34); //x add_trc_field("VC", "Indirizzo", T_X, 46, 34); //x add_trc_field("VC", "Localita", T_X, 80, 20); //x attenzione che potrebbe essere il com_dencom add_trc_field("VC", "CAP", T_X, 100, 5); //x add_trc_field("VC", "Provincia", T_X, 105, 2); //x da questo e da dencom ricaviamo il codcom add_trc_field("VC", "PartitaIVA", T_X, 107, 16); //x add_trc_field("VC", "CodicePagamento", T_X, 123, 2); //x add_trc_field("VC", "CodiceListino", T_X, 125, 3); add_trc_field("VC", "TipoDocumento", T_X, 128, 1); add_trc_field("VC", "CodiceFiscale", T_X, 129, 16); //x //Tipo record RC //-------------- add_trc_field("RC", "TipoRecord", T_X, 1, 2); //x add_trc_field("RC", "CodiceTerminale", T_N, 3, 3); //x add_trc_field("RC", "CodiceArticolo", T_X, 6, 5); //x add_trc_field("RC", "Quantita", T_Nv2N, 11, 7); //x add_trc_field("RC", "DataCarico", T_X, 18, 6); //x TText_recordset::load_file(filename); } /////////////////////////////////////////////////////////// // TAutomask : maschera principale /////////////////////////////////////////////////////////// class TUpload2Campo_mask : public TAutomask { protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: TUpload2Campo_mask(); }; bool TUpload2Campo_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { return true; } TUpload2Campo_mask::TUpload2Campo_mask() : TAutomask ("ha1300a") { } /////////////////////////////////////////////////////////// // TAutomask : maschera secondaria per inserimento nuovo cliente /////////////////////////////////////////////////////////// class TUpload2Campo_newcli_mask : public TAutomask { protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: TUpload2Campo_newcli_mask(); }; bool TUpload2Campo_newcli_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { return true; } TUpload2Campo_newcli_mask::TUpload2Campo_newcli_mask() : TAutomask ("ha1301a") { } /////////////////////////////////////// // TSkeleton_application /////////////////////////////////////// class TUpload2Campo : public THardy_transaction { bool _can_write; TAssoc_array _nuovi_clienti; protected: virtual void elabora(const TMask& mask, TLog_report& log); virtual TMask* create_mask() const; const char* fake_trans_file() const; //metodi di basso livello const TString& check_agente(TString& codice_terminale, TLog_report& log); const TString& check_articolo(TString& codart, TLog_report& log); long check_cliente(const TString& str_codcf, TLog_report& log); void check_magazzino(const TString& codmag_age, TLog_report& log); void check_causale(TString& codcaus, TLog_report& log); bool genera_incasso(TPartita& game, int nriga, int nrata, const TMovimentoPN& mov, const TBill& zio_agente, TLog_report& log) const; bool archivia_file_importato(const TString& dst_root_path, const TFilename& curr_fname, const TString& terminalino, TLog_report& log); //metodi di alto livello const TString4 elabora_SU(THardy_upload_recordset& recset, TLog_report& log); void elabora_BR(THardy_upload_recordset& recset, TLog_report& log); void elabora_VC(THardy_upload_recordset& recset, TLog_report& log); void elabora_TF(THardy_upload_recordset& recset, TLog_report& log); void elabora_SI(THardy_upload_recordset& recset, TLog_report& log); void elabora_RC(THardy_upload_recordset& recset, TLog_report& log); public: }; ///////////////////////////////////////////////////////////////////////////////////////////////// // Metodi di basso livello ///////////////////////////////////////////////////////////////////////////////////////////////// bool TUpload2Campo::archivia_file_importato(const TString& dst_root_path, const TFilename& curr_fname, const TString& terminalino, TLog_report& log) { //controllo della cartella di destinazione TFilename dst_file = dst_root_path; dst_file.add(terminalino); const bool crea_dir = make_dir(dst_file); //non riesce a crearla/trovarla! deve dare errore di grave livello! if (!crea_dir) { TString msg; msg.format(FR("Impossibile creare la cartella %s!"), (const char*)dst_file); log.log(2, msg); return false; } //se invece crea/trova la cartella -> copia il file dst_file.add(curr_fname.name()); const bool copia_riuscita = fcopy(curr_fname, dst_file); if (!copia_riuscita) { TString msg; msg.format(FR("Impossibile copiare il file %s!"), (const char*)curr_fname.name()); log.log(2, msg); return false; } //controllo dell'avvenuta copia e della correttezza del file destinazione //controllo sulle dimensioni const long src_size = fsize(curr_fname); const long dst_size = fsize(dst_file); if (src_size != dst_size) { TString msg; msg.format(FR("Copia del file %s non completata!"), curr_fname.name()); log.log(2, msg); return false; } //eliminazione del file sorgente const bool src_file_removed = remove_file(curr_fname); if (!src_file_removed) { TString msg; msg.format(FR("Impossibile eliminare il file origine %s"), curr_fname.name()); log.log(1, msg); return false; } return true; } //controlla se il terminale corrisponde ad un agente registrato e restituisce l'agente const TString& TUpload2Campo::check_agente(TString& codice_terminale, TLog_report& log) { codice_terminale.right_just(3, '0'); TString8 codice_agente = codice_terminale; codice_agente.right_just(5, '0'); const TRectype& rec_age = cache().get(LF_AGENTI, codice_agente); const TString& codage_campo = rec_age.get(AGE_CODAGE); if (codage_campo != codice_agente) { _can_write = false; TString msg; msg << TR("Codice agente ") << codice_agente << TR(" da terminale: sconosciuto"); log.log(2, msg); } return codage_campo; } //controlla che l'articolo esista su Campo const TString& TUpload2Campo::check_articolo(TString& codart, TLog_report& log) { codart.trim(); const TRectype& rec_anamag = cache().get(LF_ANAMAG, codart); const TString& articolo_campo = rec_anamag.get(ANAMAG_CODART); if (articolo_campo != codart) { _can_write = false; TString msg; msg << TR("Codice articolo ") << codart << TR(" sconosciuto su Campo"); log.log(2, msg); } return rec_anamag.get(ANAMAG_DESCR); } //controlla l'esistenza del magazzino su Campo void TUpload2Campo::check_magazzino(const TString& codmag_age, TLog_report& log) { const TString& codmag_campo = cache().get("MAG", codmag_age, "CODTAB"); if (codmag_campo != codmag_age) { _can_write = false; TString msg; msg << "Codice magazzino " << codmag_age << " sconosciuto su Campo"; log.log(2, msg); } } //controlla il cliente;se nuovo controlla che sia già stato importato nella lista dei nuovi clienti,se.. //esistente controlla che ci sia negli archivi Campo long TUpload2Campo::check_cliente(const TString& str_codcf, TLog_report& log) { long codcf = 0L; const bool new_cliente = str_codcf.find('*') >= 0; if (new_cliente) { const real* ptr = (const real*)_nuovi_clienti.objptr(str_codcf); codcf = ptr ? ptr->integer() : 0L; } else { TToken_string key_clifo; key_clifo.add("C"); key_clifo.add(str_codcf); codcf = atol(cache().get(LF_CLIFO, key_clifo, CLI_CODCF)); } //controllo effettuabile solo se il cliente è già presente (vecchio o nuovo aggiunto con la importa_VC se era _can_write) if (codcf <= 0) { _can_write = false; TString msg; msg << "Codice cliente " << str_codcf << " sconosciuto"; log.log(2, msg); } return codcf; } //aggiorna una partita con una nuova riga che riguarda l'incasso bool TUpload2Campo::genera_incasso(TPartita& game, int nriga, int nrata, const TMovimentoPN& mov, const TBill& zio_agente, TLog_report& log) const { TString msg; msg.format(FR(" %d della riga %d della partita %d/%s"), nrata, nriga, game.anno(), (const char*)game.numero()); if (!game.esiste(nriga, nrata)) // Non si sa mai col saldaconto! { msg.insert(TR("Non esiste la rata")); msg << " Creazione pagamento non assegnato."; log.log(1, msg); nriga = nrata = game.UNASSIGNED; } const TRectype& head = mov.curr(); // Creo una riga di partita di tipo pagamento e ci copio i dati della testata del movimento TRiga_partite& riga = game.new_row(); const int nrigp = riga.get_int(PART_NRIGA); riga.put(PART_TIPOMOV, tm_pagamento); riga.put(PART_SEZ, game.conto().tipo() == 'F' ? 'D' : 'A'); riga.put(PART_NREG, head.get(MOV_NUMREG)); riga.put(PART_NUMRIG, 1); riga.put(PART_DATAREG, head.get(MOV_DATAREG)); riga.put(PART_DATADOC, head.get(MOV_DATADOC)); riga.put(PART_DATAPAG, head.get(MOV_DATACOMP)); riga.put(PART_CODCAUS, head.get(MOV_CODCAUS)); riga.put(PART_NUMDOC, head.get(MOV_NUMDOC)); riga.put(PART_DESCR, head.get(MOV_DESCR)); // Creo una nuova riga di pagamento assegnado il flag di saldo TRectype new_pag(LF_PAGSCA); if (nriga > 0 && nriga < game.UNASSIGNED) { TRiga_scadenze& scad = game.rata(nriga, nrata); new_pag = scad.new_row(nrigp); // Creo nuova riga e la duplico } else //se la partita non esiste si inventa il pagamento new_pag = game.pagamento(nriga, nrata, nrigp); new_pag.put(PAGSCA_ACCSAL, 'A'); new_pag.put(PART_IMPORTO, head.get_real(MOV_TOTDOC)); //richiesta di Hardy del 04-03-2011: aggiungere il conto agente in $pagsca gruppoc-contoc-sottocontc.. //..ovvero il conto di contropartita sul pagamento const int gruppoc = zio_agente.gruppo(); const int contoc = zio_agente.conto(); const long sottocontc = zio_agente.sottoconto(); new_pag.put(PAGSCA_GRUPPOC, gruppoc); new_pag.put(PAGSCA_CONTOC, contoc); new_pag.put(PAGSCA_SOTTOCONTC, sottocontc); //..ovvero nei gruppi di contropartita const TValuta valuta(head); game.modifica_pagamento(new_pag, valuta, true); return true; } ///////////////////////////////////////////////////////////////////////////////////////////////// // Metodi di alto livello ///////////////////////////////////////////////////////////////////////////////////////////////// //SU non è un tipo record di qualche utilità const TString4 TUpload2Campo::elabora_SU(THardy_upload_recordset& recset, TLog_report& log) { TString4 codice_terminale = recset.get("CodiceTerminale").as_string(); codice_terminale.format("%03d", atoi(codice_terminale)); return codice_terminale; } //elabora clienti e loro variazioni; viene comunque eseguita per prima perchè i record VC vengono messi all'inizio void TUpload2Campo::elabora_VC(THardy_upload_recordset& recset, TLog_report& log) { //dati dal recordset di upload TString4 codice_terminale = recset.get("CodiceTerminale").as_string(); const TString8 codice_agente = check_agente(codice_terminale, log); long codcf = recset.get("CodiceCliente").as_int(); TLocalisamfile file_clifo(LF_CLIFO); //se il codice contiene un '*' -> il cliente è nuovo e va aggiunto alla lista di Campo //se invece il cliente ha un codice normale -> è un aggiornamento dei suoi dati -> controlla che esista davvero if (codcf <= 0) { //questa è un surrogato della get_next_cli considerando che vanno riempiti i clienti della serie 200000.. //..prima di intaccare eventuali clienti della serie 300000 file_clifo.zero(); file_clifo.put(CLI_TIPOCF, 'C'); file_clifo.put(CLI_CODCF, 300000); int err = file_clifo.read(_isgteq); codcf = 1; if (err == NOERR) { file_clifo.prev(); codcf += file_clifo.get_long(CLI_CODCF); } //La finestra propositiva per ora non viene usata! //finestra propositiva del nuovo codcf; viene proposto il codcf calcolato come ultimo + 1, ma l'utonto potrebbe.. //..decidere di andare a riempire un qualche 'buco' precedentemente alla cazzo creato!! /* TUpload2Campo_newcli_mask newcli_mask; newcli_mask.set(F_CODCF, codcf); FOR_EACH_MASK_FIELD(newcli_mask, f, fld) { const TFieldref* fr = fld->field(); if (fr != NULL) fld->set(recset.get(fr->name()).as_string()); } if (newcli_mask.run() == K_ENTER) {*/ //aggiunge il cliente nuovo ricodificato all'array dei nuovi clienti in modo da ricordarsi chi era.. //..quando loritroverà nei record di tipo TF,RF,SI; lo in ogni modo perchè serve anche in caso di simulazione! const TString& str_new_codcf = recset.get("CodiceCliente").as_string(); _nuovi_clienti.add(str_new_codcf, real(codcf)); file_clifo.zero(); file_clifo.put(CLI_TIPOCF, 'C'); file_clifo.put(CLI_CODCF, codcf); //ATTENZIONE!! In caso di simulazione ci si ferma qui perchè non si potrebbe inserire alcun dato, visto che.. //_can_write è comunque falso! if (_can_write) file_clifo.write(); else { TString msg; msg << "Nuovo cliente con codice provvisorio: " << str_new_codcf << "da registrare in Campo con il codice: " << codcf; log.log(0, msg); return; } } //if(codcf<=0)... //il cliente, se non nuovo, deve esistere! file_clifo.put(CLI_TIPOCF, 'C'); file_clifo.put(CLI_CODCF, codcf); int err = file_clifo.read(); //se non esiste non scrive ma continua if (err != NOERR) { _can_write = false; TString msg; msg << "Impossibile aggiornare il cliente " << codcf << ". File clifo."; log.log(2, msg); } //campi clifo const TString& ragsoc = recset.get("RagioneSociale").as_string(); file_clifo.put(CLI_RAGSOC, ragsoc); const TString& indcf = recset.get("Indirizzo").as_string(); file_clifo.put(CLI_INDCF, indcf); const TString& localita = recset.get("Localita").as_string(); file_clifo.put(CLI_LOCCF, localita); const TString& cap = recset.get("CAP").as_string(); file_clifo.put(CLI_CAPCF, cap); //modo semi-intelligente per cercare il comune dato il cap e la località const TString& codcom = cap2comune(cap, localita); file_clifo.put(CLI_COMCF, codcom); //la provincia non serve perchè si passa dal codice del comune //const TString& provincia = recset.get("Provincia").as_string(); const TString& piva = recset.get("PartitaIVA").as_string(); file_clifo.put(CLI_PAIV, piva); const TString& codpag = recset.get("CodicePagamento").as_string(); file_clifo.put(CLI_CODPAG, codpag); const TString& cofi = recset.get("CodiceFiscale").as_string(); file_clifo.put(CLI_COFI, cofi); //campi cfven //prima cerca se il record di questo c+codcf esiste già sul cfven TLocalisamfile file_cfven(LF_CFVEN); file_cfven.put(CFV_TIPOCF, 'C'); file_cfven.put(CFV_CODCF, codcf); err = file_cfven.read(); //se non c'è lo crea! if (err != NOERR) { file_cfven.zero(); file_cfven.put(CFV_TIPOCF, 'C'); file_cfven.put(CFV_CODCF, codcf); if (_can_write) err = file_cfven.write(); else err = NOERR; } //se la creazione non va a buon fine avverte if (err != NOERR) { _can_write = false; TString msg; msg << "Impossibile aggiornare il cliente " << ragsoc << ". File cfven."; log.log(2, msg); } file_cfven.put(CFV_CODAG, codice_agente); const TString& codlist = recset.get("CodiceListino").as_string(); file_cfven.put(CFV_CODLIST, codlist); //incredibilmente arriva in fondo TString msg; msg << "Cliente: " << codcf << " Terminale: " << codice_terminale; //se può scrivere... if (_can_write) { //alla fine della fiera salva il cliente e il cfven err = file_clifo.rewrite(); if (err == NOERR) err = file_cfven.rewrite(); if (err == NOERR) { msg.insert("Registrato cliente: ", 0); log.log(0, msg); } else { msg.insert("Impossibile registrare cliente: ", 0); log.log(2, msg); } } } //movimenti di incasso void TUpload2Campo::elabora_SI(THardy_upload_recordset& recset, TLog_report& log) { //dati dal recordset di upload (con i relativi controlli) TString4 codice_terminale = recset.get("CodiceTerminale").as_string(); const TString8 codice_agente = check_agente(codice_terminale, log); const TString& str_codcf = recset.get("CodiceCliente").as_string(); long codcf = check_cliente(str_codcf, log); //crea un movimento contabile pescando i dati dal recordset (e inventandosene qualcuno!) //testata const TString& str_dataincasso = recset.get("DataIncasso").as_string(); const TDate data_incasso = upload_format_date6(str_dataincasso); const TDate datareg = data_incasso; const TDate datacomp = data_incasso; TEsercizi_contabili esc; const int annoes = esc.date2esc(data_incasso); const int anno = datareg.year(); const long numdoc = recset.get("NumeroFattura").as_int(); const TString& str_datadoc = recset.get("DataFattura").as_string(); const TDate datadoc = upload_format_date6(str_datadoc); const TString4 tipodoc = recset.get("TipoDocumento").as_string(); const real incasso = recset.get("ImportoIncassato").as_real() / CENTO; //panegirico su anno partita e numero partita const TString16 str_part = recset.get("Partita").as_string(); int annopart = atoi(str_part.left(4)); // anno = primi 4 caratteri del campo partita TString8 numpart = str_part.mid(5, 7); // numero partita = 7 caratteri a partire dal sesto if (numpart.blank()) { annopart = datadoc.year(); TToken_string nd(recset.get("NumeroFattura").as_string(), '/'); numpart.format("%ld/%02d", nd.get_long(0), nd.get_int(1)); } if (annopart <= 0 || numpart.blank()) { TString msg; msg << "Partita: " << numpart << " Anno: " << anno << " non valida!"; _can_write = false; log.log(2, msg); } TConfig config(CONFIG_DITTA, "ha"); const TString& codcaus = config.get("InpCausale"); const TCausale caus(codcaus, anno); TMovimentoPN mov; TRectype& head = mov.curr(); head.put(MOV_CODCAUS, codcaus); head.put(MOV_DATAREG, datareg); head.put(MOV_DATACOMP, datacomp); TString descr; descr << "Incasso. Cliente: " << codcf << " - Agente: " << codice_agente; head.put(MOV_DESCR, descr); head.put(MOV_ANNOES, annoes); head.put(MOV_DATADOC, datadoc); head.put(MOV_NUMDOC, numdoc); head.put(MOV_TIPODOC, tipodoc); head.put(MOV_TIPOMOV, caus.tipomov()); head.put(MOV_ANNOIVA, anno); head.put(MOV_TOTDOC, incasso); long numreg = 999999L; TString msg; msg << " movimento di incasso. Cliente: " << codcf << " - Agente: " << codice_agente << " - Data: " << data_incasso; //panegirico sui conti //conto cliente TToken_string key_clifo; key_clifo.add('C'); key_clifo.add(codcf); const TRectype& rec_codcf = cache().get(LF_CLIFO, key_clifo); int gr_cli = rec_codcf.get_int(CLI_GRUPPO); int co_cli = rec_codcf.get_int(CLI_CONTO); TBill zio_clifo(gr_cli, co_cli, codcf ,'C'); //se il cliente non ha un suo conto, prova con il primo della causale incassi in configurazione if (zio_clifo.conto() <= 0) { caus.bill(1, zio_clifo); gr_cli = zio_clifo.gruppo(); co_cli = zio_clifo.conto(); zio_clifo.set(gr_cli, co_cli, codcf, 'C'); } TPartita game(zio_clifo, annopart, numpart); for (int r = game.last(); r > 0; r = game.pred(r)) { const TRiga_partite& riga = game.riga(r); if (riga.tipo() == tm_pagamento) { const TDate data_riga = riga.get_date(PART_DATAPAG); const real imp_riga = riga.get_real(PART_IMPORTO); if (data_riga == data_incasso && imp_riga == incasso) { _can_write = false; msg.insert("Doppio"); log.log(2, msg); return; } } } if (_can_write) { if (mov.write() != NOERR) { _can_write = false; msg.insert("Impossibile registrare"); log.log(2, msg); } else { msg.insert("Registrato"); log.log(0, msg); numreg = head.get_long(MOV_NUMREG); } } else { msg.insert("Controllato"); log.log(0, msg); } //conto agente const TRectype& rec_agente = cache().get(LF_AGENTI, codice_agente); int gr_age = rec_agente.get_int(AGE_GRUPPO); int co_age = rec_agente.get_int(AGE_CONTO); long sott_age = rec_agente.get_long(AGE_SOTTOCONTO); TBill zio_agente(gr_age, co_age, sott_age); //se l'agente non ha un suo conto, prova con il secondo della causale incassi in configurazione if (zio_agente.conto() <= 0) { caus.bill(2, zio_agente); gr_age = zio_agente.gruppo(); co_age = zio_agente.conto(); sott_age = zio_agente.sottoconto(); zio_agente.set(gr_age, co_age, sott_age); } //creazione vera e propria delle righe //riga 1: conto cliente TRectype& new_rmov_cli = mov.cg(-1); new_rmov_cli.put(RMV_ROWTYPE, 'K'); new_rmov_cli.put(RMV_ANNOES, annoes); new_rmov_cli.put(RMV_DATAREG, datareg); zio_clifo.put(new_rmov_cli); const char sezione_cli = caus.sezione(1); new_rmov_cli.put(RMV_SEZIONE, sezione_cli); TString descr_rmv_cli; descr_rmv_cli << "Incasso cliente " << codcf; new_rmov_cli.put(RMV_DESCR, descr_rmv_cli); zio_agente.put(new_rmov_cli, true); //conto di contropartita = conto agente new_rmov_cli.put(RMV_IMPORTO, incasso); //riga 2: conto agente TRectype& new_rmov_age = mov.cg(-1); new_rmov_age.put(RMV_ROWTYPE, 'I'); new_rmov_age.put(RMV_ANNOES, annoes); new_rmov_age.put(RMV_DATAREG, datareg); zio_agente.put(new_rmov_age); const char sezione_age = caus.sezione(2); new_rmov_age.put(RMV_SEZIONE, sezione_age); TString descr_rmv_age; descr_rmv_age << "Incasso agente " << codice_agente; new_rmov_age.put(RMV_DESCR, descr_rmv_age); zio_clifo.put(new_rmov_age, true); //conto di contropartita = conto cliente new_rmov_age.put(RMV_IMPORTO, incasso); //crea i pagamenti aggiornando anche la partita (qui si parrà la tua nobilitate!) const int nriga = game.prima_fattura(); const int nrata = 1; //metodo magicissimo per l'aggiornamento della partita con l'incasso genera_incasso(game, nriga, nrata, mov, zio_agente, log); //alla fine della fiera scrive (se può) movimento e pagamento su partita if (_can_write) { int err = mov.rewrite(); TString mov_msg; mov_msg << " movimento di incasso n.reg.: " << numreg; if (err == NOERR) { mov_msg.insert("Completato"); log.log(0, mov_msg); game.write(true); } else { _can_write = false; mov_msg.insert("Impossibile completare"); log.log(2, mov_msg); } } //if(_can_write)... } void TUpload2Campo::elabora_BR(THardy_upload_recordset& recset, TLog_report& log) { //dati dal recordset di upload TString4 codice_terminale = recset.get("CodiceTerminale").as_string(); const TString& codice_agente = check_agente(codice_terminale, log); const TString8 cod_magazzino = cache().get(LF_AGENTI, codice_agente, AGE_CODMAG); check_magazzino(cod_magazzino, log); const long curr_movmag = recset.get("NumeroDoc").as_int(); const TString& str_data_mov = recset.get("DataMov").as_string(); const TDate data_mov = upload_format_date6(str_data_mov); const int anno = data_mov.year(); TString descr; descr << "Agente: " << codice_terminale; //1) crea la testata //movimento di magazzino da riempire TMov_mag movmag; //const long numreg = atol(movmag.get_next_key()); //movmag.put(MOVMAG_NUMREG, numreg); movmag.put(MOVMAG_ANNOES, anno); movmag.put(MOVMAG_DATAREG, data_mov); movmag.put(MOVMAG_DATACOMP, data_mov); movmag.put(MOVMAG_EXNUMDOC, curr_movmag); movmag.put(MOVMAG_EXDATADOC, data_mov); movmag.put(MOVMAG_DESCR, descr); //la causale va trascodificata con l'apposita tabella &CAU const TString& caus_term = recset.get("CausaleMov").as_string(); const TString& codcaus = cache().get("&CAU", caus_term, "S7"); if (codcaus.empty()) { _can_write = false; TString msg; msg << "Causale movimento " << caus_term << " non codificata"; log.log(2, msg); } movmag.put(MOVMAG_CODCAUS, codcaus); bool go_on = true; // righe movimento di magazzino //scansione delle righe documento su record BR while (go_on) { //2) crea le righe (legge tutti i record di tipo BR successivi finchè hanno lo stesso numero documento!) //agginunge una nuova riga (solo merce, per quanto ne sappiamo) TRectype& rmovmag = movmag.new_row(); rmovmag.put(RMOVMAG_CODMAG, cod_magazzino); TString8 codart = recset.get("CodiceArticolo").as_string(); check_articolo(codart, log); rmovmag.put(RMOVMAG_CODART, codart); TToken_string key_umart; key_umart.add(codart); key_umart.add(1); const TString& um = cache().get(LF_UMART, key_umart, UMART_UM); rmovmag.put(RMOVMAG_UM, um); const TString& lotto = recset.get("CodiceLotto").as_string(); rmovmag.put(RMOVMAG_LIVGIAC, lotto); real qta = recset.get("Qta[int]").as_real(); qta += recset.get("Qta[dec]").as_real() / CENTO; rmovmag.put(RMOVMAG_QUANT, qta); //quando non trova un BR con lo stesso numero di movimento significa che le righe sono finite! go_on = recset.move_next(); if (go_on && (recset.get("TipoRecord").as_string() != "BR" || curr_movmag != recset.get("NumeroDoc").as_int())) { recset.move_prev(); //allora torna indietro di un record per riposizionarsi sull'ultimo non letto go_on = false; } } //while(go_on)... //incredibilmente arriva in fondo TString msg; msg << "Doc.: " << curr_movmag << " Terminale: " << codice_terminale; //se può scrivere... if (_can_write) { //alla fine della fiera salva il maggico movimento di magazzino TLocalisamfile file_movmag(LF_MOVMAG); int err = movmag.write(file_movmag); if (err == NOERR) { msg.insert("Registrato mov. magazzino: ", 0); log.log(0, msg); } else { msg.insert("Impossibile registrare mov. magazzino: ", 0); log.log(2, msg); } } else //..sennò avverte e basta { msg.insert("Controllato mov. magazzino: ", 0); log.log(0, msg); } } void TUpload2Campo::elabora_TF(THardy_upload_recordset& recset, TLog_report& log) { char rec_tipodoc = recset.get(DOC_TIPODOC).as_string()[0]; //i documenti di vendita annullati vanno ignorati if (rec_tipodoc == 'A' || rec_tipodoc == 'N' || rec_tipodoc <= ' ') return; //1) codice terminale (lungo 3) e codice agente (lungo 5) TString4 codice_terminale = recset.get("CodiceTerminale").as_string(); const TString& codice_agente = check_agente(codice_terminale, log); const TString8 codmag = cache().get(LF_AGENTI, codice_agente, AGE_CODMAG); check_magazzino(codmag, log); //2) Testata documento //genera una simpatico documento di cui raccatta la chiave const TString& str_datadoc = recset.get(DOC_DATADOC).as_string(); const TDate datadoc = upload_format_date6(str_datadoc); //2a) tipo documento TString4 tipodoc; switch (rec_tipodoc) { case 'F': tipodoc = ini_get_string(CONFIG_DITTA, "ha", "InpFatTip"); break; //Fatture case 'B': tipodoc = ini_get_string(CONFIG_DITTA, "ha", "InpBolTip"); break; //Bolle case 'V': tipodoc = ini_get_string(CONFIG_DITTA, "ha", "InpValTip"); break; //bolle Valorizzate: attenzione!! devono essere trasformate in 'B'olle alla creazione della numerazione di Campo case 'O': tipodoc = ini_get_string(CONFIG_DITTA, "ha", "InpOrdTip"); break; //Ordini default: { _can_write = false; TString msg; msg << "Tipo documento in input " << rec_tipodoc << " sconosciuto"; log.log(2, msg); } break; } //2b) numerazione documento //il codnum dipende dal tipo documento del terminale (F,B,O...) e dal codice del terminale //se tipo 'V' va cambiato in tipo 'B' in quanto le bolle valorizzate sono normali bolle in Campo TString4 codnum; if (rec_tipodoc == 'V') rec_tipodoc = 'B'; codnum << rec_tipodoc << codice_terminale; const TString& numerazione = cache().get("%NUM", codnum, "CODTAB"); if (numerazione != codnum) { _can_write = false; TString msg; msg << "Codice numerazione " << codnum << " sconosciuto"; log.log(2, msg); } const long ndoc = recset.get(DOC_NDOC).as_int(); TDocumento doc; doc.read('D', datadoc.year(), codnum, ndoc, _isequal, _can_write ? _lock : _nolock); //2c) tipo documento e data documento doc.put(DOC_TIPODOC, tipodoc); TTipo_documento td(tipodoc); const TString& caus_movmag = td.caus_mov(); doc.put(DOC_CAUSMAG, caus_movmag); doc.put(DOC_DATADOC, datadoc); //2d) cliente e campi collegati via cli2doc() doc.put(DOC_TIPOCF, "C"); //dato il codice cliente sul recordset (stringa di 6) risale al codice di Campo (long di 6) stabilendo.. //..eventuali relazioni con i clienti nuovi (con '*') importati nei record VC all'inizio della procedura const TString& str_codcf = recset.get(DOC_CODCF).as_string(); long codcf = check_cliente(str_codcf, log); doc.put(DOC_CODCF, codcf); doc.put(DOC_CODCFFATT, recset.get(DOC_CODCFFATT).as_int()); //usa la cli2doc per riempire tutti i campi legati al cliente TCli_for clifor('C', codcf); clifor.cli2doc(doc); //sconto in fattura, sconto totale, che cazzo sono? //TString8 scontone = recset.get(); //codice pagamento (su terminalino è lungo 2, da noi 3 e lo vogliamo zero-filled; mah?!) TString4 str_codpag = recset.get(DOC_CODPAG).as_string(); str_codpag.right_just(3, '0'); doc.put(DOC_CODPAG, str_codpag); //incasso (importo pagato) const real incasso = recset.get("Incasso").as_real() / CENTO; doc.put(DOC_IMPPAGATO, incasso); //data spedizione...datapart o datacons? (solo per ordini) //al simpatico documento appiccia tutte le righe RF che seguono il record TF.. //..dopo il magico ordinamento iniziale del recordset //intanto azzera le righe eventualmente già presenti (riscrittura) doc.destroy_rows(); //3) righe documento //scansione delle righe documento su record RF while (recset.move_next()) { if (recset.get("TipoRecord").as_string() != "RF") //quando non trova un RF significa che le righe della testata sono finite! { recset.move_prev(); //allora torna indietro di un record per riposizionarsi sull'ultimo non letto break; } //agginunge una nuova riga (solo merce, per quanto ne sappiamo) TRiga_documento& rigadoc = doc.new_row("01"); //3a) tipo cessione (fa cambiare il tipo riga o la causale di riga) const char tipocess = recset.get("TipoCessione").as_string()[0]; switch (tipocess) { case 'V': break; case 'O': rigadoc.put(RDOC_TIPORIGA, "09"); rigadoc.put(RDOC_ADDIVA, "X"); rigadoc.put(RDOC_CAUSMAG, "OMA"); break; case 'R': break; case 'S': break; default : break; } //serie delle put sulla riga documento; ricordiamo che la chiave della riga viene riempita dalla new_row //3a) articolo TString8 codart = recset.get(RDOC_CODART).as_string(); TString80 descr = check_articolo(codart, log); if (tipocess == 'O') descr << " (OMAGGIO)"; rigadoc.put(RDOC_CODART, codart); rigadoc.put(RDOC_CODARTMAG, codart); rigadoc.put(RDOC_CHECKED, "X"); rigadoc.put(RDOC_DESCR, descr); //3b) umart e qta const TString& umqta = recset.get(RDOC_UMQTA).as_string(); TLocalisamfile file_umart(LF_UMART); file_umart.setkey(2); file_umart.put(UMART_CODART, codart); file_umart.put(UMART_UM, umqta); const int err_umart = file_umart.read(); if (err_umart != NOERR) { _can_write = false; TString msg; msg << "U.m. " << umqta << " dell'articolo " << codart << " sconosciuta"; log.log(2, msg); } rigadoc.put(RDOC_UMQTA, umqta); real qta = recset.get("Qta[int]").as_real(); qta += recset.get("Qta[dec]").as_real() / CENTO; rigadoc.put(RDOC_QTA, qta); //panegirico sugli sconti TString str_sconto; real sconto[4]; sconto[0] = recset.get("Sconto1").as_real(); sconto[1] = recset.get("Sconto2").as_real(); sconto[2] = recset.get("Sconto3").as_real(); sconto[3] = recset.get("ScontoLibero").as_real(); for (int s = 0; s < 4; s++) { if (!sconto[s].is_zero()) str_sconto << real(sconto[s] / CENTO) << '+'; } str_sconto.rtrim(1); rigadoc.put(RDOC_SCONTO, str_sconto); //prezzi real prezzo_lordo = recset.get(RDOC_PREZZO).as_real(); prezzo_lordo /= 1000; rigadoc.put(RDOC_PREZZO, prezzo_lordo); //3x) iva const int aliquota_iva = recset.get("AliquotaIva").as_int(); TString4 codiva; //il codice lo si trova nella configurazione del modulo Ha (c'è un magico sheet apposito) TConfig config(CONFIG_DITTA, "ha"); TString curr_name; for (int j = 0; ; j++) { const real curr_aliq_iva = config.get("IVAaliquota", NULL, j); if (curr_aliq_iva == ZERO) break; if (curr_aliq_iva.integer() == aliquota_iva) { codiva = config.get("IVAcodice", NULL, j); break; } } rigadoc.put(RDOC_CODIVA, codiva); rigadoc.put(RDOC_LIVELLO, recset.get("CodiceLotto").as_string()); rigadoc.put(RDOC_CODMAG, codmag); //questo viene dall'agente ed è stato preso all'inizio del metodo } /* Commentato in quanto sfuggono molti errori veri 10-10-2014 const real totdoc = doc.totale_doc(); if (totdoc.is_zero()) doc.put(DOC_STATO, 5); // Evita problemi di contabilizzazione dei documenti nulli */ //incredibilmente arriva in fondo TString msg; msg << datadoc.year() << "-" << codnum << "-" << ndoc << " Terminale: " << codice_terminale << " Cliente: " << codcf; //se può scrivere... if (_can_write) { int err = doc.write(); if (err == NOERR) { msg.insert("Registrato documento: ", 0); log.log(0, msg); } else { msg.insert("Impossibile registrare documento: ", 0); log.log(2, msg); } } else //..sennò avverte e basta { msg.insert("Controllato documento: ", 0); log.log(0, msg); } } void TUpload2Campo::elabora_RC(THardy_upload_recordset& recset, TLog_report& log) { //1) codice terminale (lungo 3) e codice agente (lungo 5) TString4 codice_terminale = recset.get("CodiceTerminale").as_string(); const TString& codice_agente = check_agente(codice_terminale, log); const TRectype& rec_agente = cache().get(LF_AGENTI, codice_agente); const TString8 codmag = rec_agente.get(AGE_CODMAG); const long codcf = rec_agente.get_long(AGE_CODFORN); //cliente (legato all'agente) //2) Testata documento const TString& str_datadoc = recset.get("DataCarico").as_string(); const TDate datadoc = upload_format_date6(str_datadoc); const int anno = datadoc.year(); //2a) numerazione e tipo documento TConfig hardy(CONFIG_DITTA, "ha"); const TString4 codnum = hardy.get("CarDocNum"); const TString4 tipodoc = hardy.get("CarDocTip"); //2b) documento vero e proprio (stessi campi del caso tipo record = TF) TDocumento doc; doc.put(DOC_CODNUM, codnum); doc.put(DOC_ANNO, anno); doc.put(DOC_PROVV, "D"); doc.put(DOC_TIPODOC, tipodoc); doc.put(DOC_STATO, "1"); doc.put(DOC_DATADOC, datadoc); doc.put(DOC_TIPOCF, "C"); doc.put(DOC_CODCF, codcf); TTipo_documento td(tipodoc); const TString& caus_movmag = td.caus_mov(); doc.put(DOC_CAUSMAG, caus_movmag); TCli_for clifor('C', codcf); clifor.cli2doc(doc); doc.destroy_rows(); // righe documento di carico bool go_on = true; //scansione delle righe documento su record RC while (go_on) { //3) crea le righe (legge tutti i record di tipo RC successivi) TRiga_documento& rigadoc = doc.new_row("01"); //serie delle put sulla riga documento; ricordiamo che la chiave della riga viene riempita dalla new_row //3a) articolo, um, codmag TString8 codart = recset.get("CodiceArticolo").as_string(); const TString& descr = check_articolo(codart, log); rigadoc.put(RDOC_CODART, codart); rigadoc.put(RDOC_CODARTMAG, codart); rigadoc.put(RDOC_CHECKED, "X"); rigadoc.put(RDOC_DESCR, descr); TToken_string key_umart; key_umart.add(codart); key_umart.add(1); const TString& um = cache().get(LF_UMART, key_umart, UMART_UM); rigadoc.put(RDOC_UMQTA, um); const real qta = recset.get("Quantita").as_real() / CENTO; rigadoc.put(RDOC_QTA, qta); rigadoc.put(RDOC_CODMAG, codmag); //quando non trova un RC significa che le righe sono finite! go_on = recset.move_next(); if (go_on && (recset.get("TipoRecord").as_string() != "RC")) { recset.move_prev(); //allora torna indietro di un record per riposizionarsi sull'ultimo non letto go_on = false; } } //incredibilmente arriva in fondo TString msg; msg << anno << "-" << codnum << " Terminale: " << codice_terminale << " Cliente: " << codcf; //se può scrivere... if (_can_write) { int err = doc.write(); if (err == NOERR) { msg.insert("Registrato documento di carico: ", 0); log.log(0, msg); } else { msg.insert("Impossibile registrare documento di carico: ", 0); log.log(2, msg); } } else //..sennò avverte e basta { msg.insert("Controllato documento di carico: ", 0); log.log(0, msg); } } static int upload_cmp(const TSortable& o1, const TSortable& o2, void* jolly) { const TFilename f1 = (const TString&)o1; const TFixed_string s1 = f1.ext()+1; if (s1.empty()) return +1; const TFilename f2 = (const TString&)o2; const TFixed_string s2 = f2.ext()+1; if (s2.empty()) return -1; TToken_string d1(s1, '_'); TToken_string d2(s2, '_'); int cmp = 0; const int seq[6] = { 2, 1, 0, 3, 4, 5 }; // upload.dGG_MM_AAAA_hh_mm_ss for (int i = 0; i < 6 && cmp == 0; i++) { const int tok = seq[i]; cmp = d1.get_int(tok) - d2.get_int(tok); } return cmp; } void TUpload2Campo::elabora(const TMask& mask, TLog_report& log) { /* Per il momento preferiscono agire manualmente // a) stoppa il concentratore chiudi_concentratore(); // b) scarica il concentratore per generare il file upload.d bool carica = scarica_concentratore(); // c) rilancia il concentratore in modalità trasmissione trasmetti_concentratore(); // d) esegue le elaborazioni if (carica) */ { //creazione del filename dei files da importare TFilename src_files = _input_path; //una volta si importavano tutti i files di tipo upload*.d; poi si è passati ad importare solo upload.d e basta! src_files.add("upload.d*"); TString_array src_files_list; int n_files_d = list_files(src_files, src_files_list); if (n_files_d > 0) { src_files_list.TArray::sort(upload_cmp, NULL); const TString& u = src_files_list.row(n_files_d-1); if (u.ends_with(".d", true)) // Ignoro upload.d in quanto duplicato nell'ultimo upload.dGG_MM_AAAA_hh_mm_ss n_files_d--; } TProgind pi(n_files_d, TR("Acquisizione files in corso..."), true, true); //scandisce i files uno ad uno for (int i = 0; i < n_files_d; i++) { if (!pi.addstatus(1)) break; const TFilename curr_fname = src_files_list.row(i); pi.set_text(curr_fname); //file corrente in fase di elaborazione THardy_upload_recordset recset(curr_fname); const long items = recset.items(); //ordinamento del file in memoria secondo l'ordine stabilito nella tipi_record "SU|VC|TF|RF|SI|BR|RC"; recset.sort(ordina_upload); TString msg; #ifdef DBG msg << "D:/dati/hardy/" << "cazzone_" << curr_fname.name_only() << ".txt"; recset.save_as(msg); #endif //creazione progind e log msg.cut(0); msg << "Elaborazione file " << curr_fname << " in corso..."; TProgind pi(items, msg, true, true); msg.cut(0); msg << "File " << curr_fname.name(); log.log(0, ""); log.log(0, msg); log.log(0, ""); //parametro di controllo; solo se resta true fino alla fine il documento viene writato //solo in caso di elaborazione definitiva può diventare true; vale per ogni upload*.d, in modo da archiviare.. //..quelli buoni _can_write = false; if (mask.get_bool(F_DEFINITIVO)) _can_write = true; //codice terminalino; viene preso dal tipo record SU (è comunque presente in ogni tipo record) ed usato per l'archiviazione.. //..del file se correttamente importato TString4 terminalino; //giro su tutti i record del terribile recordset per l'acquisizione dei dati for (bool ok = recset.move_first(); ok; ok = recset.move_next()) { if (!pi.addstatus(1)) break; //acquisizione tipo record da riga corrente del file di input TString4 tipo_record = recset.rec_type(); tipo_record.trim(); //Sequenza di ordinamento dei record "SU|VC|TF|RF|SI|BR|RC": NON ATTENTATEVI A CAMBIARLA O NON FUNZIONA PIU' UN CAZZO!! const int pos = tipi_record.get_pos(tipo_record); //trattazione dei vari tracciati record switch (pos) { case 0: //tipo record: SU (SetUp...ovvero agente) terminalino = elabora_SU(recset, log); //non serve a una cippa! break; case 1: //tipo record: VC (nuovi clienti e Variazioni Cliente) elabora_VC(recset, log); break; case 2: //tipo record: TF (Testata Fattura) elabora_TF(recset, log); break; case 3: //tipo record: RF (Riga Fattura) //elabora_RF(recset, log); //non serve! lo fa l'elaborazione di testata break; case 4: //tipo record: SI (incasso documenti) elabora_SI(recset, log); break; case 5: //tipo record: BR (righe movimenti magazzino) elabora_BR(recset, log); break; case 6: //tipo record: RC (Richiesta Carico) elabora_RC(recset, log); break; default: //se il tipo record non esiste nella lista dei tipi record si incazza e lo scrive! { TString msg; msg << "Tipo record non riconosciuto '" << tipo_record << "' alla riga " << (recset.current_row() + 1); log.log(2, msg); } break; } //switch(pos).. } //for (bool ok... (acquisizione di un file) log.log(0, ""); //sequenza di archiviazione del file di upload se elaborato con successo in via definitiva if (_can_write) { if (archivia_file_importato(_archive_path, curr_fname, terminalino, log)) { msg.cut(0); msg << "Archiviato file " << curr_fname.name_only(); log.log(0, msg); } } } //for (int i = 0; i < n_files_d;... (giro su tutti i files tipo upload*.d) } //if (carica) } TMask* TUpload2Campo::create_mask() const { TMask* mask = new TUpload2Campo_mask; mask->set(F_INPUT_PATH, _input_path); mask->set(F_ARCHIVE_PATH, _archive_path); //mask->set(F_CONC_PATH, _conc_path); //mask->set(F_TRANS_PATH, _trans_path); return mask; } const char* TUpload2Campo::fake_trans_file() const { return "164"; } int ha1300(int argc, char* argv[]) { TUpload2Campo a; a.run(argc, argv, TR("Importazione dati da file")); return 0; }