#include #include #include #include #include #include #include "lvlib.h" #include "../ve/velib.h" #include "clifo.h" #include "cfven.h" #include "lvcondv.h" #include "lvrcondv.h" #include "lvrconsplan.h" #include "lv2600a.h" ///////////////////////////// //// TARTICOLI_KEY //// ///////////////////////////// //classe TArticoli_key class TArticoli_key: public TToken_string { public: const long codcf(); const char* codart(); const TDate data(); TArticoli_key(long codcf, TString& codart, TDate& data); TArticoli_key(const char* key); }; //CODCF: metodo che restituisce il codcf dalla TToken_string chiave degli articoli const long TArticoli_key::codcf() { return get_int(0); } //CODART: metodo che restituisce il codart dalla TToken_string chiave degli articoli const char* TArticoli_key::codart() { return get(1); } //DATA: metodo che restituisce la data dalla TToken_string chiave degli articoli const TDate TArticoli_key::data() { return (TDate)get(2); } //metodi costruttori TArticoli_key::TArticoli_key(long codcf, TString& codart, TDate& data) { add(codcf); add(codart.trim()); add(data.date2ansi()); } TArticoli_key::TArticoli_key(const char* key):TToken_string(key) { } ////////////////////////////// //// TDOCUMENTI_KEY //// ////////////////////////////// //classe TDocumenti_key class TDocumenti_key: public TToken_string { public: const char* codnum(); const int anno(); const long ndoc(); const int idriga(); const long codcf(); const char* codart(); const TDate data(); TDocumenti_key(int anno, long ndoc, int idriga, long codcf, TString& codart, TDate& data); TDocumenti_key(const char* key); }; //CODNUM: metodo che restituisce il codnum dalla TToken_string chiave dei documenti const char* TDocumenti_key::codnum() { return get(0); } //ANNO: metodo che restituisce l'anno dalla TToken_string chiave dei documenti const int TDocumenti_key::anno() { return get_int(1); } //NDOC: metodo che restituisce il numero documento dalla TToken_string chiave dei documenti const long TDocumenti_key::ndoc() { return get_int(2); } //IDRIGA: metodo che restituisce l'idriga dalla TToken_string chiave dei documenti const int TDocumenti_key::idriga() { return get_int(3); } //CODCF: metodo che restituisce il codcf dalla TToken_string chiave dei documenti const long TDocumenti_key::codcf() { return get_int(4); } //CODART: metodo che restituisce il codart dalla TToken_string chiave dei documenti const char* TDocumenti_key::codart() { return get(5); } //DATA: metodo che restituisce la data dalla TToken_string chiave dei documenti const TDate TDocumenti_key::data() { return (TDate)get(6); } //metodi costruttori TDocumenti_key::TDocumenti_key(int anno, long ndoc, int idriga, long codcf, TString& codart, TDate& data) { add(ini_get_string(CONFIG_DITTA, "lv", "NUM_RIT(0)")); add(anno); add(ndoc); add(idriga); add(codcf); add(codart.trim()); add(data.date2ansi()); } TDocumenti_key::TDocumenti_key(const char* key):TToken_string(key) { } ////////////////////////////////// //// TQUANTITA_CONATATE //// ////////////////////////////////// //classe TQuantita_contate class TQuantita_contate: public TObject { real _numpezzi; real _numrotti; public: const real get_pezzi() const; const real get_rotti() const; void set_pezzi(const real qta); void set_rotti(const real qta); void add_pezzi(const real qta); void add_rotti(const real qta); bool is_empty(); TQuantita_contate(real pezzi = ZERO, real = ZERO); }; //GET_PEZZI: metodo che restituisce il numero di pezzi contati const real TQuantita_contate::get_pezzi() const { return _numpezzi; } //GET_ROTTI: metodo che restituisce il numero di pezzi rotti contati const real TQuantita_contate::get_rotti() const { return _numrotti; } //SET_PEZZI: metodo che setta il numero di pezzi contati void TQuantita_contate::set_pezzi(const real qta) { _numpezzi = qta; } //SET_ROTTI: metodo che setta il numero di pezzi rotti contati void TQuantita_contate::set_rotti(const real qta) { _numrotti = qta; } //ADD_PEZZI: metodo che somma i pezzi contati alla quantià che già esisteva void TQuantita_contate::add_pezzi(const real qta) { _numpezzi += qta; } //ADD_PEZZI: metodo che somma i pezzi rotti contati alla quantià che già esisteva void TQuantita_contate::add_rotti(const real qta) { _numrotti += qta; } //IS_EMPTY: metodo che resituisce true se entrambe le quantità sono a zero bool TQuantita_contate::is_empty() { return _numpezzi == 0 && _numrotti == 0; } //metodo costruttore TQuantita_contate::TQuantita_contate(real pezzi, real rotti) { set_pezzi(pezzi); set_rotti(rotti); } ///////////////////////////////// //// TARTICOLI_CONTATI //// ///////////////////////////////// //classe TArticoli_contati class TArticoli_contati: public TAssoc_array { public: TQuantita_contate* quantita(long codcf, TString& codart, TDate& data, bool create = false); }; //QUANTITA: metodo che cerca nel TAssoc_array le quantità contate in base ai parametri passati //e lo crea in automatico se il parametro create vale "true" TQuantita_contate* TArticoli_contati::quantita(long codcf, TString& codart, TDate& data, bool create) { TArticoli_key key(codcf, codart, data); TQuantita_contate* qc = (TQuantita_contate*)objptr(key); if(qc == NULL && create) { qc = new TQuantita_contate(); add(key, qc); } return qc; } ///////////////////////////////// //// TACQUISIZIONE_MSK //// ///////////////////////////////// //classe TAcquisizione_msk class TAcquisizione_msk: public TAutomask { protected: virtual bool on_field_event(TOperable_field& o,TField_event e,long jolly); public: TAcquisizione_msk(); }; //ON_FIELD_EVENT: metodo che gestisce gli eventi sui campi della maschera bool TAcquisizione_msk::on_field_event(TOperable_field& f,TField_event e,long jolly) { return true; } //metodo costruttore che precarica i campi di interesse sulla maschera TAcquisizione_msk::TAcquisizione_msk():TAutomask("lv2600a") { TConfig configlv(CONFIG_DITTA, "lv"); const TString& path = configlv.get("PathContapezzi"); set(F_PATH, path); TSheet_field& sheet = sfield(F_SHEET_NAME); for (int i = 0; ; i++) { TString nomefile = configlv.get("FileName", NULL, i); if (nomefile.empty()) break; TToken_string& row = sheet.row(-1); row.add(nomefile); } sheet.force_update(); } /////////////////////////////////// //// TACQUISIZIONE_CACHE //// /////////////////////////////////// //classe TAcquisizione_cache class TAcquisizione_cache : public TCache { TString4 _codnum, _tipodoc, _stato; long _ndoc; protected: virtual void discarding(const THash_object* obj); virtual TObject* key2obj(const char* key); public: TDocumento& doc(const TDate& gg, const long cc); TAcquisizione_cache(); }; //DISCARDING: metodo che salva un documento sul disco prima di eliminarlo dalla cache void TAcquisizione_cache::discarding(const THash_object* obj) { TDocumento& doc = (TDocumento&)obj->obj(); TToken_string orderkey; orderkey.add(RDOC_CODART); doc.sort_rows(orderkey); int err = doc.rewrite(); } //KEY2OBJ: metodo che sceglie il documento giusto da disco in modo da poterlo continuare, o lo crea se non c'è TObject* TAcquisizione_cache::key2obj(const char* key) { TToken_string chiave(key); TDate datadoc = chiave.get(); const TDate datagen(TODAY); TDate dadata = datadoc; TDate adata = datagen; adata.addmonth(); const long codcf = chiave.get_long(); if(_ndoc == 0) { TString query2; query2 << "USE DOC\n" << "FROM PROVV=\"D\" ANNO=" << datadoc.year() << " CODNUM=\"" << _codnum << "\"\n" << "TO PROVV=\"D\" ANNO=" << datadoc.year() << " CODNUM=\"" << _codnum << "\""; TISAM_recordset sporco(query2); if(sporco.move_last()) _ndoc = sporco.get(DOC_NDOC).as_int(); } TString query = "USE DOC KEY 2\n"; query << "SELECT (TIPODOC=\"" << _tipodoc << "\")&&(STATO=\"" << _stato <<"\")\n"; query << "FROM TIPOCF=C CODCF=" << codcf << " PROVV=D ANNO=" << datadoc.year() << " DATADOC=" << datadoc << " CODNUM=" << _codnum << "\n"; query << "TO TIPOCF=C CODCF=" << codcf << " PROVV=D ANNO=" << datadoc.year() << " DATADOC=" << datadoc << " CODNUM=" << _codnum << "\n"; TISAM_recordset rset(query); TDocumento* doc = NULL; if (rset.move_first()) doc = new TDocumento(rset.cursor()->curr()); else { TToken_string key; key.add('C'); key.add(codcf); const int codindsp = atoi(cache().get(LF_CFVEN, key, CFV_CODINDSP)); TLaundry_contract cont(codcf, codindsp, datadoc); const TString8 codcont = cont.get(LVCONDV_CODCONT); TString query1 = "USE LVRCONSPLAN KEY 3\n"; query1 << "FROM CODCF=" << codcf << " CODCONT=" << codcont << " DTCONS=#DADATA\n"; query1 << "TO CODCF=" << codcf << " CODCONT=" << codcont << " DTCONS=#ADATA\n"; TISAM_recordset consegne(query1); consegne.set_var("#DADATA", ++dadata); consegne.set_var("#ADATA", adata); consegne.move_first(); const TDate dataprco = consegne.get(LVRCONSPLAN_DTCONS).as_date(); const int coditi = consegne.get(LVRCONSPLAN_CODITI).as_int(); const long codaut = consegne.get(LVRCONSPLAN_CODAUT).as_int(); //recupero i dati di interesse dal cliente const TRectype& clifo = cache().get(LF_CLIFO, key); const TString4 codpag = clifo.get(CLI_CODPAG); const long codabi = clifo.get_long(CLI_CODABI); const long codcab = clifo.get_long(CLI_CODCAB); const TString80 iban = clifo.get(CLI_IBAN); //reupero la cuasale di magazzino di testata const TString16 causmag = cache().get("%TIP", _tipodoc, "S9"); //recupero i dati di interesse dal file CFVEN const TRectype& cfven = cache().get(LF_CFVEN, key); const long codabipr = cfven.get_long(CFV_CODABIPR); const long codcabpr = cfven.get_long(CFV_CODCABPR); const bool ragdoc = cfven.get_bool(CFV_RAGGDOC); const TString8 codag1 = cfven.get(CFV_CODAG1); const TString4 codmez = cfven.get(CFV_CODSPMEZZO); const TString4 codporto = cfven.get(CFV_CODPORTO); const TString4 codnote1 = cfven.get(CFV_CODNOTESP1); const TString4 codnote2 = cfven.get(CFV_CODNOTESP2); const TString4 codnote = cfven.get(CFV_CODNOTE); const TString8 codvet1 = cfven.get(CFV_CODVETT1); const TString8 codvet2 = cfven.get(CFV_CODVETT2); const TString8 codvet3 = cfven.get(CFV_CODVETT3); const real speseinc = cfven.get_real(CFV_PERCSPINC); const TString4 catven = cfven.get(CFV_CATVEN); const bool addbolli = cfven.get_bool(CFV_ADDBOLLI); const TString8 codlist = cfven.get(CFV_CODLIST); const TString4 codzona = cfven.get(CFV_CODZONA); //gestione sconto TString sconto; const char tpgest = ini_get_string(CONFIG_DITTA, "ve", "GESSCO")[0]; switch(tpgest) { case 'P': sconto = cfven.get(CFV_SCONTO); break; //Percentuale su anagrafica cliente case 'T': sconto = cache().get("%SCC", cfven.get(CFV_CODSCC), "S1"); break; //Gestione tabella sconti case 'A': //Gestione archivio sconti { TConfig ditta(CONFIG_DITTA, "ve"); TLocalisamfile sconti(LF_SCONTI); sconti.put("TIPO", "I"); if(ditta.get_bool("SCOKEY", "ve", 1)) sconti.put("CODCAT", cfven.get(CFV_CATVEN)); TString16 cod; if(ditta.get_bool("SCOKEY", "ve", 2)) cod.format("%-2s", (const char*)cfven.get(CFV_CODSCC)); else cod = " "; if(ditta.get_bool("SCOKEY", "ve", 3)) { TString8 tmp; tmp.format("%-2s", (const char*)cfven.get(CFV_CODZONA)); cod << tmp; } else cod << " "; if(ditta.get_bool("SCOKEY", "ve", 4)) cod << clifo.get(CLI_CODPAG); sconti.put("CODART", cod); if (sconti.read() == NOERR) sconto = sconti.get("SCONTO"); } case 'N': //sconto non gestito default: break; } if (cont.get(LVCONDV_CODNUM).empty()) { doc = new TDocumento('D', datadoc.year(), _codnum, ++_ndoc); doc->put(DOC_TIPODOC, _tipodoc); } else { doc = new TDocumento('D', datadoc.year(), cont.get(LVCONDV_CODNUM), ++_ndoc); doc->put(DOC_TIPODOC, cont.get(LVCONDV_TPDOC)); } doc->put(DOC_STATO, _stato); doc->put(DOC_DATADOC, datadoc); doc->put(DOC_TIPOCF, 'C'); doc->put(DOC_CODCF, codcf); doc->put(DOC_CODCONT, codcont); if(codindsp > 0) doc->put(DOC_CODINDSP, codindsp); doc->put(DOC_CODPAG, codpag); doc->put(DOC_CAUSMAG, causmag); doc->put(DOC_CODABIA, codabi); doc->put(DOC_CODCABA, codcab); doc->put(DOC_IBAN, iban); doc->put(DOC_CODABIP, codabipr); doc->put(DOC_CODCABP, codcabpr); doc->put(DOC_CODAG, codaut); doc->put(DOC_CODAGVIS, codag1); doc->put(DOC_CODSPMEZZO, codmez); doc->put(DOC_ZONA, codzona); doc->put(DOC_CODPORTO, codporto); doc->put(DOC_CODNOTESP1, codnote1); doc->put(DOC_CODNOTESP2, codnote2); doc->put(DOC_CODNOTE, codnote); doc->put(DOC_CODVETT1, codvet1); doc->put(DOC_CODVETT2, codvet2); doc->put(DOC_CODVETT3, codvet3); doc->put(DOC_CATVEN, catven); doc->put(DOC_CODLIST, codlist); doc->put(DOC_CAUSMAG, causmag); doc->put(DOC_PERCSPINC, speseinc); doc->put(DOC_ADDBOLLI, addbolli); doc->put(DOC_SCONTOPERC, sconto); doc->put("DATACON", datadoc); //data conteggio doc->put("DATAGEN", datagen); //data generazione del documento doc->put("DATAPRCO", dataprco); //data prevista consegna doc->put("CODITI", coditi); //codice itinerario } return doc; } //DOC: metodo che restituisce un puntatore ad un documento identificato dalla coppia data - cliente TDocumento& TAcquisizione_cache::doc(const TDate& gg, const long cc) { TString16 key; key << gg.date2ansi() << '|' << cc; return *(TDocumento*)objptr(key); } //metodo costruttore di una cache di 17 elementi TAcquisizione_cache::TAcquisizione_cache() : TCache(17) { _codnum = ini_get_string(CONFIG_DITTA, "lv", "NUM_RIT(0)"); _tipodoc = ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_RIT(0)"); _stato = cache().get("%TIP", _tipodoc, "S2").left(1); _ndoc = 0; } /////////////////////////////////// //// TCONFRONTO_CACHE //// /////////////////////////////////// //classe TConfronto_cache class TConfronto_cache : public TCache { TString4 _codnum, _tipodoc, _stato; protected: virtual void discarding(const THash_object* obj); virtual TObject* key2obj(const char* key); public: TDocumento& doc(const TDate& gg, const long cc); TConfronto_cache(); }; //DISCARDING: metodo che salva un documento sul disco prima di eliminarlo dalla cache void TConfronto_cache::discarding(const THash_object* obj) { TDocumento& doc = (TDocumento&)obj->obj(); if (!doc.empty()) int err = doc.rewrite(); } //KEY2OBJ: metodo che sceglie il documento giusto da disco in modo da poterlo continuare, o lo crea se non c'è TObject* TConfronto_cache::key2obj(const char* key) { TToken_string chiave(key); TDate datadoc = chiave.get(); const TDate datagen(TODAY); TDate adata = datagen; adata.addmonth(); const long codcf = chiave.get_long(); TString query = "USE DOC KEY 2\n"; query << "SELECT (TIPODOC=\"" << _tipodoc << "\")&&(STATO=\"" << _stato <<"\")\n"; query << "FROM TIPOCF=C CODCF=" << codcf << " PROVV=D ANNO=" << datadoc.year() << " DATADOC=" << datadoc << " CODNUM=" << _codnum << "\n"; query << "TO TIPOCF=C CODCF=" << codcf << " PROVV=D ANNO=" << datadoc.year() << " DATADOC=" << datadoc << " CODNUM=" << _codnum << "\n"; TISAM_recordset rset(query); TDocumento* doc = NULL; if (rset.move_first()) doc = new TDocumento(rset.cursor()->curr()); else doc = new TDocumento(); return doc; } //DOC: metodo che restituisce un puntatore ad un documento identificato dalla coppia data - cliente TDocumento& TConfronto_cache::doc(const TDate& gg, const long cc) { TString16 key; key << gg.date2ansi() << '|' << cc; return *(TDocumento*)objptr(key); } //metodo costruttore di una cache di 17 elementi TConfronto_cache::TConfronto_cache() : TCache(17) { _codnum = ini_get_string(CONFIG_DITTA, "lv", "NUM_RIT(0)"); _tipodoc = ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_RIT(0)"); _stato = cache().get("%TIP", _tipodoc, "S2").left(1); } //////////////////////////////////////////// //// TACQUISIZIONE_LAVANDERIE_APP //// //////////////////////////////////////////// //classe TAcquisizione_lavanderie_app class TAcquisizione_lavanderie_app : public TSkeleton_application { TAcquisizione_msk* _msk; TString4 _auto; TString4 _gr; protected: virtual bool create(); virtual bool destroy(); bool elabora_file(const TString& file, TLog_report &rep, TArticoli_contati& articoli, int& nrighe, int& nrsalt); void controlla_documenti(TLog_report& rep, TArticoli_contati& articoli, TAssoc_array& documenti); void genera_documenti(TLog_report& rep, TAssoc_array& documenti); void sposta_file(const TString& file); public: bool transfer(); virtual void main_loop(); }; //CREATE: metodo costruttore bool TAcquisizione_lavanderie_app::create() { _msk = new TAcquisizione_msk(); TSheet_field& sheet = _msk->sfield(F_SHEET_NAME); sheet.set_auto_append(); //se ho più di un parametro, allora lo sto lanciando da linea di comando, e ne devo tenere conto if (argc() > 2) { _auto = argv(2); _auto = _auto.right(1); _gr = argv(3); _gr = _gr.right(1); } else { _auto = "N"; _gr = ""; } if (_gr == "S" || _gr.empty()) _msk->set(F_RICGIRI, "X"); else _msk->set(F_RICGIRI, ""); open_files(LF_DOC, LF_RIGHEDOC); return TSkeleton_application::create(); } //DESTROY: metodo distruttore bool TAcquisizione_lavanderie_app::destroy() { delete _msk; return TApplication::destroy(); } //ELABORA_FILE: metodo che effettivamente fa l'elaborazione del file bool TAcquisizione_lavanderie_app::elabora_file(const TString& file, TLog_report& rep, TArticoli_contati& articoli, int& nrighe, int& nrsalt) { //scandisco il file solo se esiste TFilename strname = file; TScanner s(file); while (s.ok()) { TString80 riga = s.line(); if (riga.blank()) continue; TDate datadoc; long codcf = 0; TString8 codcf_str; TString80 codart; long qta; long rotti; long ndoc = 0; TString16 tipo_conteggio; TString80 operatore; //controllo quale tracciato record devo seguire if (riga.len() == 34) // -> MONTANARI { nrighe += 1; //leggo i campi dalla riga del file const int d = atoi(riga.mid(0,2)); const int m = atoi(riga.mid(2,2)); const int y = atoi(riga.mid(4,4)); if (d > 0 && d <= 31 && m > 0 && m <= 12 && y > 2000) { datadoc = TDate(d, m, y); if (datadoc < _msk->get_date(F_DADATA) || datadoc > _msk->get_date(F_ADATA)) { nrsalt += 1; continue; } codcf_str = riga.mid(8,6); codcf = atol(codcf_str); codart = riga.mid(14,8); qta = atol(riga.mid(22,6)); rotti = atol(riga.mid(28,6)); } else continue; } else if (riga.len() == 121) // ->SKEMA { //leggo i campi dalla riga del file const int y = atoi(riga.mid(0,4)); const int m = atoi(riga.mid(4,2)); const int d = atoi(riga.mid(6,2)); if (d > 0 && d <= 31 && m > 0 && m <= 12 && y > 2000) { codcf_str = riga.mid(28,20); codcf = atol(codcf_str); datadoc = TDate(d, m, y); codart = riga.mid(8,20); qta = atoi(riga.mid(48,11)); ndoc = atoi(riga.mid(59,11)); switch (atoi(riga.mid(70,11))) { case 1: tipo_conteggio = "Automatico"; break; case 2: tipo_conteggio = "Manuale"; break; case 3: tipo_conteggio = "Scarto"; break; default: break; } operatore = riga.mid(81,40); } else continue; } TToken_string key; key.add('C'); key.add(codcf); const int codindsp = atoi(cache().get(LF_CFVEN, key, CFV_CODINDSP)); TLaundry_contract cont(codcf, codindsp, datadoc); const TRectype& rcont = cont.row(codart.trim()); if(rcont.empty()) { TString str; str << "L'articolo " << codart << " non è previsto nel contratto del cliente " << codcf; warning_box(str); } TQuantita_contate* qc = articoli.quantita(codcf, codart.trim(), datadoc, true); //se la chiave è già presente nel TAssoc_array, chiedi cosa fare delle quantità //altrimenti aggiungila con la rispettiva al TAssoc_array con la quantità appena conteggiata if (!qc->is_empty()) { TString str; str << "ATTENZIONE: è già presente un conteggio per il cliente " << codcf << " sull'articolo " << codart << "\n" << "Quantità conteggio attuale: " << qta << " Quantità conteggio precedente: " << qc->get_pezzi() << "\n" << "Si desidera sommare le quantità?\n" << "(SI -> Somma NO -> Ignora Conteggio ANNULLA -> Sosituisci il conteggio precedente)\n"; KEY k = yesnocancel_box(str); switch (k) { case K_YES: qc->add_pezzi(qta); qc->add_rotti(rotti); break; //sommo le quantità case K_NO: break; //lascio tutto com'è default: qc->set_pezzi(qta); qc->set_rotti(rotti); break; //sostituisco le quantità } } else { qc->set_pezzi(qta); qc->set_rotti(rotti); } } return true; } //CONTROLLA_DOCUMENTI: metodo che si occupa di controllare se i dati che sto inserendo in questo momento sono //già stati inseriti in documenti precedenti, chiedendo cosa fare di volta in volta void TAcquisizione_lavanderie_app::controlla_documenti(TLog_report& rep, TArticoli_contati& articoli, TAssoc_array& documenti) { TConfronto_cache ca; bool found = false; FOR_EACH_ASSOC_OBJECT(articoli, obj, key, itm) { TArticoli_key keyart(key); const TQuantita_contate* qc = (TQuantita_contate*)itm; //recupero i dati dalla chiave del TAssoc_array degli articoli int codcf = keyart.codcf(); TString80 codart = keyart.codart(); TDate datadoc = keyart.data(); //recupero i dati dal contenuto del TAssoc_array degli articoli TQuantita_contate* quantita = new TQuantita_contate(ZERO, ZERO); quantita->set_pezzi(qc->get_pezzi()); quantita->set_rotti(qc->get_rotti()); TDocumento& doc = ca.doc(datadoc, codcf); if (doc.empty()) { //preparo la chiave per il TAssoc_array dei documenti TDocumenti_key keydoc(datadoc.year(), 0, 0, codcf, codart, datadoc); //aggiungo la riga corrispondente documenti.add(keydoc, quantita); } else { int idriga; for (idriga = 1; idriga <= doc.rows(); idriga++) { //cerco se esiste già una riga sul documento selezionato per quell'articolo TRiga_documento& rdoc = doc[idriga]; TString80 codart_doc = rdoc.get(RDOC_CODART); codart_doc.trim(); if (codart_doc == codart) { found = true; TString str; str << "ATTENZIONE: è già presente un buono di ritiro per il cliente " << codcf << " sull'articolo " << codart << "\n" << "Quantità conteggio: " << quantita->get_pezzi() << " Quantità buono di ritiro: " << rdoc.get_int(RDOC_QTAGG1) << "\n" << "Si desidera sommare le quantità?\n" << "(SI -> Somma NO -> Ignora Conteggio ANNULLA -> Modifica Buono)\n"; KEY k = yesnocancel_box(str); switch (k) { case K_YES: quantita->add_pezzi(rdoc.get_real(RDOC_QTAGG1)); quantita->add_rotti(rdoc.get_real(RDOC_QTA)); break; //sommo le quantità case K_NO: quantita->set_pezzi(rdoc.get_real(RDOC_QTAGG1)); quantita->set_rotti(rdoc.get_real(RDOC_QTA)); break; //lascio tutto com'è default: break; //sostituisco le quantità } break; } } if (!found) idriga = 0; //preparo la chiave per il TAssoc_array dei documenti TDocumenti_key keydoc(datadoc.year(), doc.get_long(DOC_NDOC), idriga, codcf, codart, datadoc); documenti.add(keydoc, quantita); } } ca.destroy(); } //metodo che effettivamente genera i buoni di ritiro, se l'utente ha confermato la sua intenzione a crearli void TAcquisizione_lavanderie_app::genera_documenti(TLog_report& rep, TAssoc_array& documenti) { TAcquisizione_cache ca; const bool giri = _msk->get_bool(F_RICGIRI); FOR_EACH_ASSOC_OBJECT(documenti, obj, key, itm) { TDocumenti_key keydoc(key); const TString4 codnum = keydoc.codnum(); const int anno = keydoc.anno(); const int ndoc = keydoc.ndoc(); const int idriga = keydoc.idriga(); const int codcf = keydoc.codcf(); const TString80 codart = keydoc.codart(); const TDate datadoc = keydoc.data(); TQuantita_contate* qc = (TQuantita_contate*)itm; const real qtacon = qc->get_pezzi(); const real qtarotti = qc->get_rotti(); TToken_string key; key.add('C'); key.add(codcf); const int codindsp = atoi(cache().get(LF_CFVEN, key, CFV_CODINDSP)); TLaundry_contract cont(codcf, codindsp, datadoc); const TString8 codcont = cont.get(LVCONDV_CODCONT); TDate oggi(TODAY); TDocumento& doc = ca.doc(datadoc, codcf); if (!giri) doc.put("DATAPRCO", oggi); if (doc.rows() > 0 && (idriga > 0 && idriga <= doc.rows())) { TRiga_documento& rdoc = doc[idriga]; rdoc.put(RDOC_QTAGG1, qtacon); rdoc.put(RDOC_QTA, qtarotti); } else { const TRectype& anamag = cache().get(LF_ANAMAG, codart); TRiga_documento& rdoc = doc.new_row("22"); rdoc.put(RDOC_CODART, codart); rdoc.put(RDOC_DESCR, anamag.get(ANAMAG_DESCR)); rdoc.put(RDOC_CODARTMAG, codart); rdoc.put(RDOC_CHECKED, 'X'); rdoc.put(RDOC_CODAGG1, ini_get_string(CONFIG_DITTA, "lv", "CAUSLAV")); rdoc.put(RDOC_QTAGG1, qtacon); rdoc.put(RDOC_QTA, qtarotti); rdoc.put(RDOC_CODIVA, anamag.get(ANAMAG_CODIVA)); } if (!doc.get_date("DATAPRCO").ok() && giri) { TString msg; msg << TR("Il documento ") << doc.get(DOC_NDOC) << TR(" del ") << doc.get(DOC_DATADOC) << TR(" del cliente ") << codcf << TR(" non ha data di prevista consegna."); rep.log(1,msg); } } if (ca.empty()) { warning_box(TR("ATTENZIONE: il file importato non ha generato nessun documento; controllare che il tracciato record sia coerente")); return; } else ca.destroy(); } //SPOSTA_FILE: metodo che sposta cambiando nome i file elaborati durante la generazione dei buoni void TAcquisizione_lavanderie_app::sposta_file(const TString& file) { TFilename fileori = file; TFilename path = fileori.path(); path.add("elaborati"); make_dir(path); TString strname; strname.format("%06d_%06d_%s", TDate(TODAY).date2ansi(), daytime(), (const char*)fileori.name()); TFilename filedest = path; filedest.add(strname); //se la ciopia è andata a buon fine, creo un file .old vuoto e cancello il file .dat if (fcopy(fileori, filedest)) { TFilename fileold; fileold = fileori.path(); TString strn = fileori.name_only(); strn << ".old"; fileold.add(strn); fclose(fopen(fileold, "w")); fileori.fremove(); } } //TRANSFER: metodo che scorre i campi nome e, se sono pieni, richiama il metodo //ELABORA_FILE(), che effettivamente fa l'elaborazione bool TAcquisizione_lavanderie_app::transfer() { //prendo il path dalla maschera const TString& path = _msk->get(F_PATH); TSheet_field& sheet = _msk->sfield(F_SHEET_NAME); TFilename file; TLog_report logrep("Aquisizione da contapezzi"); logrep.kill_duplicates(true); TArticoli_contati articoli; TAssoc_array documenti; int nrighe = 0; int nrsalt = 0; //per ogni riga dello sheet, leggo il suo contenuto, se contiene dei caratteri jolly //preparo la lista dei file che soddisfano la maschera in quella directory e li elaboro //tutti, altrimenti elaboro esattamente il file che è scritto sullo sheet bool elaborato = false; bool esiste = false; FOR_EACH_SHEET_ROW(sheet, r1, row1) { if(row1->full()) { if (row1->find('/') >= 0 || row1->find('\\') >= 0) file = *row1; else { file = path; file.add(*row1); } if (file.find('*') >= 0 || file.find('?') >= 0) { TString_array lista_file; list_files(file, lista_file); FOR_EACH_ARRAY_ROW(lista_file, r2, row2) { TFilename strname = *row2; if (strname.exist()) { esiste = true; elaborato = elabora_file(*row2, logrep, articoli, nrighe, nrsalt); } } } else if(file.exist()) { esiste = true; elaborato = elabora_file(file, logrep, articoli, nrighe, nrsalt); } if (!esiste) { TString str; str << "ATTENZIONE: non è stato trovato nessun file da elaborare"; warning_box(str); } } } if(elaborato) { controlla_documenti(logrep, articoli, documenti); bool genera = true; if (_auto == "A") { if (nrsalt > 0) { TString str; str << "Sono stati ricevuti " << nrighe << " record, di cui " << nrighe - nrsalt << " sono stati elaborati correttamente" << " e " << nrsalt << " ignorati.\nSi desidera procedere con la generazione dei buoni di ritiro?"; if (!yesno_box(str)) genera = false; } } else { TString str; str << "Sono stati ricevuti " << nrighe << " record, di cui " << nrighe - nrsalt << " sono stati elaborati correttamente" << " e " << nrsalt << " ignorati.\nSi desidera procedere con la generazione dei buoni di ritiro?"; if (!yesno_box(str)) genera = false; } if (nrsalt == 0 || genera) { genera_documenti(logrep, documenti); //diagnostica TAssoc_array buoni; FOR_EACH_ASSOC_OBJECT(documenti, obj, key, itm) { TDocumenti_key tmp = (TDocumenti_key)key; TDoc_key kdoc(tmp.anno(), tmp.codnum(), tmp.ndoc()); if (!buoni.is_key(kdoc)) buoni.add(kdoc, kdoc); } TString str; if (buoni.items() > 1) str << "Sono stati generati " << buoni.items() << " buoni di ritiro."; else str << "E' stato generato " << buoni.items() << " buono di ritiro."; message_box(str); FOR_EACH_SHEET_ROW(sheet, r1, row1) { if(row1->full()) { if (row1->find('/') >= 0 || row1->find('\\') >= 0) file = *row1; else { file = path; file.add(*row1); } if (file.find('*') >= 0 || file.find('?') >= 0) { TString_array lista_file; list_files(file, lista_file); FOR_EACH_ARRAY_ROW(lista_file, r2, row2) { TFilename strname(*row2); if (strname.exist()) sposta_file(*row2); } } else if (file.exist()) sposta_file(file); } } } if (_auto != "A") { TReport_book buc; buc.add(logrep); if (buc.pages() > 0) buc.preview(); if (genera) message_box(TR("Generazione terminata")); else message_box(TR("Generazione interrotta")); } _msk->send_key(K_SPACE, DLG_QUIT); } return true; } void TAcquisizione_lavanderie_app::main_loop() { //lo lancio in automatico da linea di comando if (_auto == "A") _msk->send_key(K_SPACE, DLG_OK); while (_msk->run() == K_ENTER) transfer(); } int lv2600(int argc, char *argv[]) { TAcquisizione_lavanderie_app a; a.run (argc, argv, "Acquisizione bolle di rientro/ritiro"); return TRUE; }