#include #include #include #include #include #include "lvlib.h" #include "lvcondv.h" #include "lvrcondv.h" #include "lvrconsplan.h" #include "../mg/clifogiac.h" #include "../ve/pacchi.h" #include "lv2900a.h" /////////////////////////// //// TRIGA_PACCO //// /////////////////////////// //classe TRiga_pacco class TRiga_pacco: public TRectype { public: TRiga_pacco & operator =(const TRiga_pacco& rpacco); bool read(const TString& codpacco, const long codriga = 1); const TString& codpacco() const; const TToken_string& key() const; const TString& articolo() const; const real quantita() const; const TString& um() const; const TDate data() const; const long cliente() const; const TDate databo() const; const bool annullato() const; const TToken_string& rigabolla() const; const long movmag() const; void set_key(const char* codpacco, const int codriga = 1); void set_articolo(const char* codart); void set_quantita(const real qta); void set_um(const char* um); void set_data(const TDate& data); void set_cliente(const long codcf); void set_databo(const TDate& data); void set_annullato(const bool ann); void set_rigabolla(const int anno, const char* codnum, const long ndoc, const long idriga); void set_movmag(const long movmag); bool is_annullato(); bool is_associato(); TRiga_pacco(const TRectype& rec); TRiga_pacco(const TRiga_pacco& rpacco); TRiga_pacco(const char* codpacco, const long codriga = 1); TRiga_pacco(); }; //READ: cerca una riga pacco in base alla chiave primaria bool TRiga_pacco::read(const TString& codpacco, const long codriga) { if (codpacco.full()) // Campo obbligatorio! { TString80 key; key.format("%s|%ld", codpacco, codriga); *((TRectype*)this) = cache().get(LF_PACCHI, key); } else zero(); return ok(); } //CODPACCO: metodo che restituisce il codice univoco del pacco const TString& TRiga_pacco::codpacco() const { return get(PACCHI_CODPACCO); } //KEY: metodo che restiuisce la chiave univoca del record analizzato (per le lavanderie CODRIGA sempre 1) const TToken_string& TRiga_pacco::key() const { TToken_string& k = get_tmp_string(); k.add(get(PACCHI_CODPACCO)); k.add(get(PACCHI_CODRIGA)); return k; } //ARTICOLO: metodo che restituisce il codice articolo specificato in questa riga const TString& TRiga_pacco::articolo() const { return get(PACCHI_CODART); } //QUANTITA: metodo che restituisce il numero dei pezzi nella confezione const real TRiga_pacco::quantita() const { return get_real(PACCHI_QTA); } //UM: metodo che restituisce l'unità di misura const TString& TRiga_pacco::um() const { return get(PACCHI_UM); } //DATA: metodo che restituisce la data in cui il pacco è creato const TDate TRiga_pacco::data() const { return get_date(PACCHI_DATA); } //CLIENTE; metodo che restituisce il codice del cliente a cui è stato assegnato il pacco const long TRiga_pacco::cliente() const { return get_long(PACCHI_CODCF); } //DATA: metodo che restituisce la data in cui il pacco è stato assegnato a qualcuno const TDate TRiga_pacco::databo() const { return get_date(PACCHI_DATABO); } //ANNULLATO: metodo che ritorna true se il pacco è stato annullato const bool TRiga_pacco::annullato() const { return get_bool(PACCHI_ANNULLATO); } //RIGABOLLA: metodo che restituisce una TToken_string contenete alla riga del documento che ha consegnato il pacco const TToken_string& TRiga_pacco::rigabolla() const { TToken_string& bolla = get_tmp_string(); bolla.add(get_char(PACCHI_PROVV)); bolla.add(get_int(PACCHI_ANNO)); bolla.add(get(PACCHI_CODNUM)); bolla.add(get_int(PACCHI_NDOC)); bolla.add(get_int(PACCHI_IDRIGA)); return bolla; } //MOVMAG: metodo che restituisce i riferimenti al movimento di magazzino generato dal pacco const long TRiga_pacco::movmag() const { return get_long(PACCHI_MGNUMREG); } //SET_KEY: metodo che setta la chiave (da usare su un TRiga_pacco vuota) void TRiga_pacco::set_key(const char* codpacco, const int codriga) { put(PACCHI_CODPACCO, codpacco); put(PACCHI_CODRIGA, codriga); } //SET_ARTICOLO: metodo che setta il codice articolo sul record corrente void TRiga_pacco::set_articolo(const char* codart) { put(PACCHI_CODART, codart); } //SET_QUANTITA: metodo che setta la quantita sul record corrente void TRiga_pacco::set_quantita(const real qta) { put(PACCHI_QTA, qta); } //SET_UM: metodo che setta l'unità di misura void TRiga_pacco::set_um(const char* um) { put(PACCHI_UM, um); } //SET_DATA: metodo che setta la data di creazione del record corrente void TRiga_pacco::set_data(const TDate& data) { put(PACCHI_DATA, data); } //SET_CLIENTE: metodo che setta il codice cliente sul record corrente void TRiga_pacco::set_cliente(const long codcf) { put(PACCHI_CODCF, codcf); } //SET_DATA: metodo che setta la data di evasione sul record corrente void TRiga_pacco::set_databo(const TDate& data) { put(PACCHI_DATABO, data); } //SET_ANNULLATO: metodo che setta il flag di annullato void TRiga_pacco::set_annullato(const bool ann) { put(PACCHI_ANNULLATO, ann); } //SET_RIGABOLLA: metodo che setta i riferimenti alla riga di bolla che evade il pacco sul record corrente void TRiga_pacco::set_rigabolla(const int anno, const char* codnum, const long ndoc, const long idriga) { put(PACCHI_PROVV, 'D'); put(PACCHI_ANNO, anno); put(PACCHI_CODNUM, codnum); put(PACCHI_NDOC, ndoc); put(PACCHI_IDRIGA, idriga); } //SET_MOVMAG: metodo che setta il movimento di magazzino generato dal pacco void TRiga_pacco::set_movmag(const long movmag) { put(PACCHI_MGNUMREG, movmag); } //IS_ANNULATO: metodo che restituisce "true" se il campo annullato sul record attuale è 'S' bool TRiga_pacco::is_annullato() { return get_bool(PACCHI_ANNULLATO); } //IS_ASSOCIATO: metodo che restitusce "true" se il campo cliente è valorizzato bool TRiga_pacco::is_associato() { return get_int(PACCHI_CODCF) && 1; } //Metodi costruttori TRiga_pacco::TRiga_pacco(const TRectype& rec) : TRectype(rec) { } TRiga_pacco::TRiga_pacco(const TRiga_pacco& rpacco) : TRectype(rpacco) { } TRiga_pacco::TRiga_pacco(const char* codpacco, const long codriga) : TRectype(LF_PACCHI) { read(codpacco, codriga); } TRiga_pacco::TRiga_pacco() : TRectype(LF_PACCHI) { zero(); } //////////////////////// //// TDOC_KEY //// //////////////////////// //classe TDoc_key class TDoc_key: public TToken_string { public: const char provv(); const int anno(); const char* codnum(); const long ndoc(); TDoc_key(const int anno, const TString& codnum, const long ndoc, const char provv = 'D'); TDoc_key(const char* key); }; //CODNUM: metodo che restituisce il codnum dalla TToken_string chiave dei documenti const char TDoc_key::provv() { return get(0)[0]; } //ANNO: metodo che restituisce l'anno dalla TToken_string chiave dei documenti const int TDoc_key::anno() { return get_int(1); } //CODNUM: metodo che restituisce il codnum dalla TToken_string chiave dei documenti const char* TDoc_key::codnum() { return get(2); } //NDOC: metodo che restituisce il numero documento dalla TToken_string chiave dei documenti const long TDoc_key::ndoc() { return get_int(3); } //metodi costruttori TDoc_key::TDoc_key(const int anno, const TString& codnum, const long ndoc, const char provv) { add(provv); add(anno); add(codnum); add(ndoc); } TDoc_key::TDoc_key(const char* key):TToken_string(key) { } //////////////////////////// //// 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(); 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(); 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); 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 { TLaundry_contract cont(codcf, 0, 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(); doc = new TDocumento('D', datadoc.year(), _codnum, ++_ndoc); doc->put(DOC_TIPODOC, _tipodoc); 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); 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); void sposta_file(const TFilename& file); bool genera_documenti(const TFilename& file, TAssoc_array& documenti); void prepara_movimenti(const TFilename& file, TAssoc_array& movimenti); 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; //a seconda del bottone premuto esegui un metodo diverso switch (f.dlg()) { case DLG_IMPORT: if(e == fe_button) { if (elabora_file(file)) { sposta_file(file); message_box(TR("Importazione dei dati terminata")); } } break; case DLG_PACKTCLI: if(e == fe_button) { genera_documenti(file, documenti); 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(); //lancia la stampa dei documenti ve1 -2 per ogni documento preparato TString str; str << "ve1 -2 " << codnum << ' ' << anno << ' ' << provv << ' '; FOR_EACH_ASSOC_OBJECT(documenti, obj, key, itm) { TDoc_key kdoc(key); const int ndoc = kdoc.ndoc(); str.cut(18); str << ndoc << ' ' << ndoc << " S"; TExternal_app stampa(str); } } message_box(TR("Generazione dei documenti terminata")); } 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); if (genera_movmag(movimenti)) message_box(TR("Generazione dei movimenti di magazzino terminata terminata")); } break; default: break; } return true; } //ELABORA_FILE: metodo che importa il file e prepara la tabella pacchi bool TConta_pulito_msk::elabora_file(const TFilename& file) { if (!file.exist()) { warning_box(TR("ATTENZIONE: il file che si desidera importare non esiste!")); return false; } TBaseisamfile f(LF_PACCHI); TScanner s(file); while (s.ok()) { TString riga = s.line(); if (riga.blank()) continue; TRiga_pacco* rp = new TRiga_pacco(); rp->set_key(riga.left(50)); rp->set_articolo(riga.mid(50, 20)); rp->set_quantita(atoi(riga.mid(70, 8))); rp->set_data((TDate)riga.mid(78, 8)); int codcf = atoi(riga.mid(86, 6)); if(codcf > 0) { rp->set_cliente(codcf); //eventualmente vuoto rp->set_databo((TDate)riga.mid(92, 8)); //eventualmente vuoto } const bool ann = riga.mid(100, 1) == 'S' ? true : false; rp->set_annullato(ann); //recupero l'unità di misura principale di quest'articolo TToken_string key; key.add(riga.mid(50, 20)); key.add(1); const TRectype& umart = cache().get(LF_UMART, key); 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) { //se esite un file da importare, lo importo e lo sposto if (file.exist()) { elabora_file(file); sposta_file(file); } TBuoni_cache ca; //inizializzo le variabili di interesse TDate dadata(TODAY); TDate adata(TODAY); 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\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); continue; } //recupero i dati di interesse dal pacco const long codcf = rp.cliente(); const TDate datadoc = rp.databo(); const TString& codart = rp.articolo(); const real quantita = rp.quantita(); //instanzio un contratto e la corrispondente riga contratto per l'articolo che sto analizzando TLaundry_contract cont(codcf, 0, 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"); //leggo se devo scrivere il prezzo sulla bolla const bool prinbo = cont.get_bool(LVCONDV_STPRZBOL); //instanzio una cache sulla tabella del magazzino const TRectype& anamag = cache().get(LF_ANAMAG,codart); //recupero i dati di interesse dall'anagrafica di magazzino const TString80 descr = anamag.get(ANAMAG_DESCR); //recupero i valori delle dotazione temporanea dal magazzino del cliente TLocalisamfile magcli(LF_CLIFOGIAC); magcli.put(CLIFOGIAC_ANNOES, datadoc.year()); magcli.put(CLIFOGIAC_TIPOCF, 'C'); magcli.put(CLIFOGIAC_CODCF, codcf); magcli.put(CLIFOGIAC_INDSPED, 0); //in realtà è da leggere dal contratto magcli.put(CLIFOGIAC_CODART, codart); magcli.put(CLIFOGIAC_NRIGA, 1); //leggo il record corrispondente magcli.read(); long dottmp = magcli.get_long(CLIFOGIAC_DOTTM); long dotod = magcli.get_long(CLIFOGIAC_DOTOD); //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 = 0; 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); rdoc.add("DOTOD", quantita); if(dtmp) rdoc.add("DOTMP", quantita); 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); rdoc.put(RDOC_QTAGG1, quantita); rdoc.put("DOTOD", dotod); rdoc.add("DOTOD", quantita); if(dtmp) { rdoc.put("DOTMP", dottmp); rdoc.add("DOTMP", quantita); } 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,rcont.get_real(LVRCONDV_PRZDTTMP)); rdoc.put(RDOC_SCONTO,rcont.get(LVRCONDV_SCONTPERC)); //sconto } //scrivo il magazzino TString8 magazzino; TString8 magazzinoc; magazzino << ini_get_string(CONFIG_DITTA, "lv", "CODMAG") << ini_get_string(CONFIG_DITTA, "lv", "CODMAGN"); 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); //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.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) { //se esite un file da importare, lo importo e lo sposto if (file.exist()) { elabora_file(file); sposta_file(file); } //inizializzo le variabili di interesse TDate dadata(TODAY); TDate adata(TODAY); 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\n"; query << "FROM DATABO=#DADATA\n"; query << "TO DATABO=#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(); //se il pacco risulta annullato, lo elimino if(rp.is_annullato()) { rp.remove(pacchi); continue; } //recupero i dati di interesse dalla riga pacchi const real quantita = rp.quantita(); const TString80 codart = rp.articolo(); 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(codart)) { real& qta = *(real*)articoli->objptr(codart); qta += quantita; } else articoli->add(codart, quantita); } } //GENERA_MOVMAG: metodo che genera i movimenti di magazzino dai pacchi bool TConta_pulito_msk::genera_movmag(TAssoc_array& movimenti) { const TString4 causale = ini_get_string(CONFIG_DITTA, "lv", "CAUCARPA"); 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_first()) nummov += mov.get(MOVMAG_NUMREG).as_int(); TLocalisamfile movi(LF_MOVMAG); //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); 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, codart, qta) { //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); 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, codart); rmovmag.put(RMOVMAG_CODCAUS, causale); 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"); const TString& file = configlv.get("FilePulito"); set(F_PATH, path); set(F_FNAME, file); //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); if (tmp.left(2) == "-C") { _percli = true; if (tmp.len() > 2) _codcf = atoi(tmp.sub(2)); else _codcf = 0; _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); } else { _auto = "N"; _percli = false; _permag = false; _codcf = 0; _giri = ""; _print = ""; } } ///////////////////////////////// //// 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; }