#include #include #include #include #include #include #include #include "lvlib.h" #include "lvcondv.h" #include "lvrcondv.h" #include "lvrconsplan.h" #include "../mg/clifogiac.h" #include "lv2900a.h" //////////////////////////// //// TBUONI_CACHE //// //////////////////////////// //classe TBuoni_cache class TBuoni_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); TBuoni_cache(); }; //DISCARDING: metodo che salva un documento sul disco prima di eliminarlo dalla cache void TBuoni_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* TBuoni_cache::key2obj(const char* key) { TToken_string chiave(key); TDate datadoc = chiave.get(0); const TDate datagen(TODAY); TDate dadata = datadoc; TDate adata = datagen; adata.addmonth(); const long codcf = chiave.get_long(); const TDate datadausare = ini_get_bool(CONFIG_DITTA, "lv", "DataBcon") ? datagen : datadoc; if(_ndoc == 0) { TString query2; query2 << "USE DOC\n" << "FROM PROVV=\"D\" ANNO=" << datadausare.year() << " CODNUM=\"" << _codnum << "\"\n" << "TO PROVV=\"D\" ANNO=" << datadausare.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=" << datadausare.year() << " DATADOC=" << datadausare << " CODNUM=" << _codnum << "\n"; query << "TO TIPOCF=C CODCF=" << codcf << " PROVV=D ANNO=" << datadausare.year() << " DATADOC=" << datadausare << " 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(); TString8 codaut = consegne.get(LVRCONSPLAN_CODAUT).as_string().right(5); codaut.trim(); //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); if(codaut.empty()) codaut = cfven.get(CFV_CODAG); //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); if(ini_get_bool(CONFIG_DITTA, "lv", "DataBcon")) { doc->put(DOC_DATADOC, datagen); //modifica 18/03/2010 richiesta da Diana2000 per i clienti che consegnano tutti i giorni if(ini_get_bool(CONFIG_DITTA, "lv", "ConDom")) { TDate datacon(TODAY); ++datacon; if(datacon.wday() == 7) ++datacon; doc->put(DOC_DATAPART, datacon); } } else 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& TBuoni_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 TBuoni_cache::TBuoni_cache() : TCache(17) { _codnum = ini_get_string(CONFIG_DITTA, "lv", "NUM_GEN"); _tipodoc = ini_get_string(CONFIG_DITTA, "lv", "TIPODOC_GEN"); _stato = cache().get("%TIP", _tipodoc, "S2").left(1); _ndoc = 0; } ///////////////////////////////// //// TCONTA_PULITO_MSK //// ///////////////////////////////// //classe TConta_pulito_msk class TConta_pulito_msk: public TAutomask { TString4 _auto; TString4 _giri; bool _percli; bool _permag; long _codcf; TString4 _print; protected: virtual bool on_field_event(TOperable_field& o,TField_event e,long jolly); bool elabora_file(const TFilename& file, TLog_report& logrep); void sposta_file(const TFilename& file); bool genera_documenti(const TFilename& file, TAssoc_array& documenti, TLog_report& logrep); void prepara_movimenti(const TFilename& file, TAssoc_array& movimenti, TLog_report& logrep); bool genera_movmag(TAssoc_array& movimenti); public: TConta_pulito_msk(); }; //ON_FIELD_EVENT: metodo che gestisce gli eventi sui campi della maschera bool TConta_pulito_msk::on_field_event(TOperable_field& f,TField_event e,long jolly) { //prendo il path dalla maschera const TString& path = get(F_PATH); const TString& fname = get(F_FNAME); TFilename file = path; file.add(fname); TAssoc_array documenti; TAssoc_array movimenti; TLog_report logrep(""); //a seconda del bottone premuto esegui un metodo diverso switch (f.dlg()) { case DLG_IMPORT: if(e == fe_button) { if (elabora_file(file, logrep)) { sposta_file(file); if (_auto != "A") message_box(TR("Importazione dei dati terminata")); } } break; case DLG_PACKTCLI: if(e == fe_button) { genera_documenti(file, documenti, logrep); if (documenti.items() > 0) { //capisci se devi stampare dalla maschera se non è stato lanciato da linea di comando char print = _print[0]; if (_print.empty()) print = get_bool(F_STAMPA) ? 'S' : 'N'; if (print == 'S') { //preparo il pezzo fisso della linea di comando per richiamare la stampa dei documenti TDoc_key kd(documenti.get_hashobj()->key()); const TString4 codnum = kd.codnum(); const int anno = kd.anno(); const char provv = kd.provv(); long andoc = 0; long dandoc = 999999L; FOR_EACH_ASSOC_OBJECT(documenti, obj, key, itm) \ { TDoc_key& dk = *(TDoc_key*)itm; const long ndoc = dk.ndoc(); if (ndoc < dandoc) dandoc = ndoc; if (ndoc > andoc) andoc = ndoc; } //lancia la stampa dei documenti ve1 -2 da documento a documento TString80 str; str << "ve1 -2 " << codnum << ' ' << anno << ' ' << provv << ' ' << dandoc << '-' << andoc << " S D"; TExternal_app stampa(str); stampa.run(); } if (_auto != "A") message_box(TR("Generazione dei documenti terminata")); } else if (_auto == "A") logrep.log(2, "Non è stato possibile generare nessun documento con i parametri fissati"); else message_box(TR("Non è stato possibile generare nessun documento con i parametri fissati")); } break; case DLG_PACKTMAG: if(e == fe_button) { prepara_movimenti(file, movimenti, logrep); if (movimenti.items() > 0) { genera_movmag(movimenti); if (_auto != "A") message_box(TR("Generazione dei movimenti di magazzino terminata")); } else if (_auto == "A") logrep.log(2, "Non è stato possibile generare nessun movimento di magazzino con i parametri fissati"); else message_box(TR("Non è stato possibile generare nessun movimento di magazzino con i parametri fissati")); } break; default: break; } TReport_book buc; buc.add(logrep); //genero il file .log che contiene gli errori if (buc.pages() > 0) { TString str = file.name_only(); str << ".log"; TFilename log = file.path(); log.add(str); buc.export_text(log, false); } if(_auto == "A") send_key(K_SPACE, DLG_QUIT); return true; } //ELABORA_FILE: metodo che importa il file e prepara la tabella pacchi bool TConta_pulito_msk::elabora_file(const TFilename& file, TLog_report& logrep) { if (!file.exist()) { if (_auto == "A") logrep.log(2, "ATTENZIONE: il file che si desidera importare non esiste!"); else warning_box(TR("ATTENZIONE: il file che si desidera importare non esiste!")); return false; } TLocalisamfile f(LF_PACCHI); TScanner s(file); while (s.ok()) { TString riga = s.line(); if (riga.blank()) continue; TString80 codpacco = riga.left(50); codpacco.trim(); TString80 codart = riga.mid(50,20); codart.trim(); real qta = atoi(riga.mid(70, 8)) / CENTO; TDate data(atoi(riga.mid(78, 2)), atoi(riga.mid(80, 2)), atoi(riga.mid(82, 4))); long codcf = atol(riga.mid(86, 6)); const bool ann = riga.mid(100, 1)[0] == 'S' ? true : false; if(ann) { TRiga_pacco rp(codpacco); rp.set_data(data); rp.set_annullato(ann); rp.set_movmag(-1); rp.rewrite(f); } else { TRiga_pacco rp; rp.set_key(codpacco); rp.set_articolo(codart); rp.set_quantita(qta); rp.set_data(data); if (codcf > 0L) { rp.set_cliente(codcf); //eventualmente vuoto TDate databo(atoi(riga.mid(92, 2)), atoi(riga.mid(94, 2)), atoi(riga.mid(96, 4))); rp.set_databo(databo); //eventualmente vuoto } rp.set_annullato(ann); rp.set_movmag(-1); //recupero l'unità di misura principale di quest'articolo TToken_string key; key.add(codart); key.add(1); const TRectype& umart = cache().get(LF_UMART, key); if (umart.empty()) { TString str; str << "ATTENZIONE: non è stata trovata nessuna unità di misura valida per l'articolo " << codart; if (_auto == "A") logrep.log(2, str); else warning_box(str); } else { TString4 um = umart.get(UMART_UM); rp.set_um(um); } rp.write(f); } } return true; } //SPOSTA_FILE: metodo che sposta il file elaborato in una sottocartella e gli cambia nome //aggiungendo data e ora dell'elaborazione void TConta_pulito_msk::sposta_file(const TFilename& 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); if (fcopy(fileori, filedest)) fileori.fremove(); } //GENERA_DOCUMENTI: metodo che genera i documenti partendo dal file pacchi bool TConta_pulito_msk::genera_documenti(const TFilename& file, TAssoc_array& documenti, TLog_report& logrep) { //se esite un file da importare, lo importo e lo sposto if (file.exist()) { elabora_file(file, logrep); sposta_file(file); } TBuoni_cache ca; //inizializzo le variabili di interesse TDate dadata(TODAY); dadata.addyear(-1); TDate adata(TODAY); adata.addyear(); long codcf = _codcf; //se non l'ho lanciato da linea di comando, inizializzo le variabili //ai dati presi dalla maschera if (_auto != "A") { dadata = get_date(F_DADATA); adata = get_date(F_ADATA); codcf = get_long(F_CODCF); } //seleziona tutti i record del file pacchi da data a data e eventualmente filtrati per cliente //che risultano associati a un cliente ma che non hanno una bolla associata TString query; query << "USE PACCHI KEY 2\n"; query << "SELECT (NDOC=0)&&(CODCF>0)&&(MGNUMREG<0)\n"; query << "FROM DATA=#DADATA"; if (codcf > 0) query << " CODCF=" << codcf; query << "\n"; query << "TO DATA=#ADATA"; if (codcf > 0) query << " CODCF=" << codcf; TISAM_recordset selrighe(query); selrighe.set_var("#DADATA", dadata); selrighe.set_var("#ADATA", adata); selrighe.move_first(); TLocalisamfile& pacchi = selrighe.cursor()->file(); //scorro tutti i pacchi trovati for (bool ok = selrighe.move_first(); ok; ok = selrighe.move_next()) { TRiga_pacco rp = selrighe.cursor()->curr(); //se il pacco risulta annullato, lo elimino if(rp.is_annullato()) { rp.remove(pacchi); rp.rewrite(pacchi); continue; } //recupero i dati di interesse dal pacco const long codcf = rp.cliente(); const TDate datadoc = rp.databo(); const TString80 codart = rp.articolo(); const real quantita = rp.quantita(); //instanzio un contratto e la corrispondente riga contratto per l'articolo che sto analizzando 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); bool dtmp = false; if (datadoc >= rcont.get_date(LVRCONDV_INDTTMP) && datadoc <= rcont.get_date(LVRCONDV_FIDTTMP)) dtmp = true; //leggo la causale (quella su contratto ha precedenza) TString4 causale = rcont.get(LVRCONDV_CAUSLAV); if (causale.blank() || atoi(causale) == 0) causale = ini_get_string(CONFIG_DITTA, "lv", "CAUSLAV"); const TCausale_lavanderie cau(causale); const TCausale_magazzino rit(cau.causale_ritiro()); const TCausale_magazzino con(cau.causale_consegna()); //leggo se devo scrivere il prezzo sulla bolla //const bool prinbo = cont.get_bool(LVCONDV_STPRZBOL); const bool prinbo = true; //sempre a true; verrà gestita a video in futuro (27/10/2009) //instanzio una cache sulla tabella del magazzino const TRectype& anamag = cache().get(LF_ANAMAG,codart); //recupero i dati di interesse dall'anagrafica di magazzino TString descr; descr << anamag.get(ANAMAG_DESCR) << anamag.get(ANAMAG_DESCRAGG); //recupero i valori delle dotazione temporanea dal magazzino del cliente TArticolo_lavanderie& artrec = cached_article_laundry(codart, 'C', codcf, 0); //fisso l'anno esercizio TEsercizi_contabili& esc = esercizi(); const int last_esc = esc.last(); //estraggo il record corrispondente su LF_CLIFOGIAC const TRecmag_lavanderie& reclav = artrec.find_rec(last_esc); real dotod = reclav.get_real(CLIFOGIAC_DOTOD); real dottmp = reclav.get_real(CLIFOGIAC_DOTTM); //preparo il documento TDocumento& doc = ca.doc(datadoc, codcf); //tengo traccia di tutti i documenti che sto generando TDoc_key kdoc(doc.get_int(DOC_ANNO), doc.get(DOC_CODNUM), doc.get_int(DOC_NDOC)); if (!documenti.is_key(kdoc)) documenti.add(kdoc, kdoc); //azzero coditi e metto dataprco alla datadoc se non sto generando per giri if(!_giri || !get_bool(F_GIRI)) { doc.put("DATAPRCO", datadoc); doc.put("CODITI", 0); } bool found = false; //cerco eventualmente una riga documento che contiene già questo articolo; //se la trovo sommo le quantità, altrimento preparo una riga nuova for (int i = 1; i <= doc.rows(); i++) { TRiga_documento& rdoc = doc[i]; if(codart == rdoc.get(RDOC_CODART)) { rdoc.add(RDOC_QTA, quantita); rdoc.add(RDOC_QTAGG1, quantita); if(rit.sgn(s_dotod) != 0 || con.sgn(s_dotod) != 0) { real qta = (quantita * con.sgn(s_dotod)) - (quantita * rit.sgn(s_dotod)); rdoc.add("DOTOD", qta); } found = true; //scrivo i riferimenti alla bolla sul pacco rp.set_rigabolla(datadoc.year(), doc.get(DOC_CODNUM), doc.get_long(DOC_NDOC), i); rp.rewrite(pacchi); } } if(!found) { TRiga_documento& rdoc = doc.new_row("21"); rdoc.put(RDOC_CODART, codart); rdoc.put(RDOC_CODARTMAG,codart); rdoc.put(RDOC_CHECKED,'X'); rdoc.put(RDOC_GENERATA, true); if(descr.len() <= 50) rdoc.put(RDOC_DESCR, descr); else { rdoc.put(RDOC_DESCR, descr.left(50)); rdoc.put(RDOC_DESCEST, descr.sub(50)); rdoc.put(RDOC_DESCLUNGA, true); } rdoc.put(RDOC_QTA, quantita); //consegnato rdoc.put(RDOC_QTAGG1, quantita); //ritirato rdoc.put("DOTOD", dotod); if(rit.sgn(s_dotod) != 0 || con.sgn(s_dotod) != 0) { real qta = (quantita * con.sgn(s_dotod)) - (quantita * rit.sgn(s_dotod)); rdoc.add("DOTOD", qta); } if(dtmp) rdoc.put("DOTMP", dottmp); rdoc.put(RDOC_CODAGG1, causale); //gestione prezzo if (prinbo) { real prezzo; if (cont.get_int(LVCONDV_TIPOLIS) == 0) prezzo = rcont.get_real(LVRCONDV_PREZZO); else prezzo = anamag.get_real(ANAMAG_COSTSTD); rdoc.put(RDOC_PREZZO, prezzo); rdoc.put(RDOC_SCONTO,rcont.get(LVRCONDV_SCONTPERC)); //sconto } //scrivo il magazzino const TCausale_lavanderie cau(causale); TCausale_magazzino rit(cau.causale_ritiro()); TCausale_magazzino con(cau.causale_consegna()); TString8 magazzino; TString8 magazzinoc; if(rit.get("S10").full()) magazzino = rit.get("S10").mid(0,5); else magazzino << ini_get_string(CONFIG_DITTA, "lv", "CODMAG") << ini_get_string(CONFIG_DITTA, "lv", "CODMAGN"); if(con.get("S10").full()) magazzinoc = con.get("S10").mid(0,5); else magazzinoc << ini_get_string(CONFIG_DITTA, "lv", "CODMAG") << ini_get_string(CONFIG_DITTA, "lv", "CODMAGC"); rdoc.put(RDOC_CODMAG, magazzino); rdoc.put(RDOC_CODMAGC, magazzinoc); rdoc.put(RDOC_CODMAG, magazzino); rdoc.put(RDOC_CODMAGC, magazzinoc); //recupero l'unità di misura principale di quest'articolo TToken_string key; key.add(codart); key.add(1); const TString4 um = cache().get(LF_UMART, key, UMART_UM); rdoc.put(RDOC_UMQTA, um); //scrivo il codice IVA const TRectype& anamag = cache().get(LF_ANAMAG, rp.articolo()); rdoc.put(RDOC_CODIVA, anamag.get(ANAMAG_CODIVA)); //scrivo i riferimenti alla bolla sul pacco rp.set_rigabolla(datadoc.year(), doc.get(DOC_CODNUM), doc.get_long(DOC_NDOC), doc.rows() + 1); rp.set_movmag(0); rp.rewrite(pacchi); } } ca.destroy(); return true; } //PREPARA_MOVIMENTI: questo metodo prepara il TAssoc_array che contiene i movimenti da generare void TConta_pulito_msk::prepara_movimenti(const TFilename& file, TAssoc_array& movimenti, TLog_report& logrep) { //se esite un file da importare, lo importo e lo sposto if (file.exist()) { elabora_file(file, logrep); sposta_file(file); } //inizializzo le variabili di interesse TDate dadata(TODAY); dadata.addyear(-1); TDate adata(TODAY); adata.addyear(); long codcf = _codcf; //se non ho lanciato il programma da linea di comando, leggo i paramtri dalla maschera if (_auto != "A") { dadata = get_date(F_DADATA); adata = get_date(F_ADATA); codcf = get_long(F_CODCF); } //seleziona tutti i record del file pacchi da data a data che non hanno una bolla associata TString query; query << "USE PACCHI KEY 2\n"; query << "SELECT (NDOC=0)&&(CODCF=0)&&(MGNUMREG<0)\n"; query << "FROM DATA=#DADATA\n"; query << "TO DATA=#ADATA"; TISAM_recordset selrighe(query); selrighe.set_var("#DADATA", dadata); selrighe.set_var("#ADATA", adata); selrighe.move_first(); TLocalisamfile& pacchi = selrighe.cursor()->file(); //scorro tutti i pacchi trovato for (bool ok = selrighe.move_first(); ok; ok = selrighe.move_next()) { TRiga_pacco rp = selrighe.cursor()->curr(); real quantita = rp.quantita(); //se il pacco risulta annullato, storno la quantità bool annullato = rp.is_annullato(); if(annullato) quantita = - quantita; //recupero i dati di interesse dalla riga pacchi const TString80 codart = rp.articolo(); TToken_string keyarticoli; keyarticoli.add(codart); if(annullato) keyarticoli.add('S'); else keyarticoli.add('N'); TString8 ansidate; ansidate << rp.data().date2ansi(); //preparo un TAssoc_array di TAssoc_array; //il primo ha per chiave la data (in ansi) e come contenuto un TAssoc_array degli articoli //il secondo ha per chiave il codart e come contenuto le quantità TAssoc_array* articoli = (TAssoc_array*)movimenti.objptr(ansidate); if(articoli == NULL) { articoli = new TAssoc_array(); movimenti.add(ansidate, articoli); } if(articoli->is_key(keyarticoli)) { real& qta = *(real*)articoli->objptr(keyarticoli); qta += quantita; } else articoli->add(keyarticoli, quantita); //se il pacco risulta annullato, lo elimino if(annullato) { rp.remove(pacchi); rp.rewrite(pacchi); } } } //GENERA_MOVMAG: metodo che genera i movimenti di magazzino dai pacchi bool TConta_pulito_msk::genera_movmag(TAssoc_array& movimenti) { const TCausale_magazzino causale((ini_get_string(CONFIG_DITTA, "lv", "CAUCARMAG"))); TString8 magazzino; magazzino << ini_get_string(CONFIG_DITTA, "lv", "CODMAG") << ini_get_string(CONFIG_DITTA, "lv", "CODMAGP"); //cerco l'ultimo numero di chiave in movmag TISAM_recordset mov("USE MOVMAG"); long nummov = 0; if(mov.move_last()) nummov += mov.get(MOVMAG_NUMREG).as_int(); TLocalisamfile movi(LF_MOVMAG); //inizializzo le variabili di interesse TDate dadata(TODAY); dadata.addyear(-1); TDate adata(TODAY); adata.addyear(); long codcf = _codcf; //se non ho lanciato il programma da linea di comando, leggo i paramtri dalla maschera if (_auto != "A") { dadata = get_date(F_DADATA); adata = get_date(F_ADATA); codcf = get_long(F_CODCF); } //per ogni oggetto salvato in movimenti, creo un movimento di magazzino FOR_EACH_ASSOC_OBJECT(movimenti, hobj, ansidate, obj) { TEsercizi_contabili es; TDate data = (TDate)ansidate; int annoes = es.date2esc(data); TMov_mag movmag(++nummov); movmag.put(MOVMAG_ANNOES, annoes); movmag.put(MOVMAG_DATAREG, data); movmag.put(MOVMAG_CODCAUS, causale.codice()); movmag.put(MOVMAG_DATACOMP, data); //seleziona tutti i record del file pacchi da data a data che non hanno una bolla associata //per poter assegnare il riferimento al movimento di magazzino TString query; query << "USE PACCHI KEY 2\n"; query << "SELECT (NDOC=0)&&(CODCF=0)&&(MGNUMREG<0)\n"; query << "FROM DATA=#DADATA\n"; query << "TO DATA=#ADATA"; TISAM_recordset selrighe(query); selrighe.set_var("#DADATA", data); selrighe.set_var("#ADATA", data); selrighe.move_first(); TLocalisamfile& pacchi = selrighe.cursor()->file(); //scorro tutti i pacchi trovati for (bool ok = selrighe.move_first(); ok; ok = selrighe.move_next()) { TRiga_pacco rp = selrighe.cursor()->curr(); rp.set_movmag(nummov); rp.rewrite(pacchi); } TAssoc_array& articoli = *(TAssoc_array*)obj; //per ogni articolo contenuto nel secondo TAssoc_array, faccio una riga movimento di magazzino FOR_EACH_ASSOC_OBJECT(articoli, hobj1, keyarticoli, qta) { TToken_string k(keyarticoli); //recupero l'unità di misura principale di quest'articolo TToken_string key; key.add(k.get(0)); key.add(1); const TRectype& umart = cache().get(LF_UMART, key); TString4 um = umart.get(UMART_UM); const real& quantita = *(real*)qta; //faccio la nuova riga del movimento di magazzino TRectype& rmovmag = movmag.new_row(); rmovmag.put(RMOVMAG_CODMAG, magazzino); rmovmag.put(RMOVMAG_CODART, k.get(0)); rmovmag.put(RMOVMAG_CODCAUS, causale.codice()); rmovmag.put(RMOVMAG_UM, um); rmovmag.put(RMOVMAG_QUANT, quantita); } movmag.write(movi); } return true; } //metodo costruttore che precarica i campi di interesse sulla maschera TConta_pulito_msk::TConta_pulito_msk():TAutomask("lv2900a") { TConfig configlv(CONFIG_DITTA, "lv"); const TString& path = configlv.get("PathPulito"); TFilename& file = (TFilename)configlv.get("FilePulito"); //se ho più di un parametro, allora lo sto lanciando da linea di comando, e ne devo tenere conto if (main_app().argc() > 2) { _auto = main_app().argv(2); _auto = _auto.right(1); TString16 tmp = main_app().argv(3); _codcf = 0L; if (tmp.left(2) == "-C") { _percli = true; if (tmp.len() > 2) _codcf = atoi(tmp.sub(2)); _permag = false; } else { _percli = false; _permag = true; } _giri = main_app().argv(4); _giri = _giri.right(1); _print = main_app().argv(5); _print = _print.right(1); file = (TFilename)main_app().argv(6); } else { _auto = "N"; _percli = false; _permag = false; _codcf = 0L; _giri = ""; _print = ""; } TString80 f = file.name_only(); f << ".dat"; set(F_PATH, path); set(F_FNAME, f); } ///////////////////////////////// //// TCONTA_PULITO_APP //// ///////////////////////////////// //classe TConta_pulito_app class TConta_pulito_app : public TSkeleton_application { TConta_pulito_msk* _msk; TString4 _auto; char _cliormag; protected: virtual bool create(); virtual bool destroy(); public: bool transfer(); virtual void main_loop(); }; //CREATE: metodo costruttore bool TConta_pulito_app::create() { _msk = new TConta_pulito_msk(); //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); TString16 tmp = argv(3); char c = tmp.mid(1,1)[0]; switch (c) { case 'C': _cliormag = 'C'; break; case 'M': _cliormag = 'M'; break; case 'I': _cliormag = 'I'; break; default: break; } } else { _auto = ""; _cliormag = ' '; } open_files(LF_DOC, LF_RIGHEDOC); return TSkeleton_application::create(); } //DESTROY: metodo distruttore bool TConta_pulito_app::destroy() { delete _msk; return TApplication::destroy(); } //TRANSFER: metodo che decide cosa effettivamente far fare al programma a seconda delle indicazioni ricevute bool TConta_pulito_app::transfer() { return true; } void TConta_pulito_app::main_loop() { //lo lancio in automatico da linea di comando if (_auto == "A") switch(_cliormag) { case 'C': _msk->send_key(K_SPACE, DLG_PACKTCLI); break; case 'M': _msk->send_key(K_SPACE, DLG_PACKTMAG); break; case 'I': _msk->send_key(K_SPACE, DLG_IMPORT); break; default: break; } while (_msk->run() == K_ENTER) transfer(); } int lv2900(int argc, char *argv[]) { TConta_pulito_app a; a.run (argc, argv, "Elaborazioni pulito"); return TRUE; }