#include #include #include #include #include #include "../db/dblib.h" #include "../ve/velib.h" #include "ps0920.h" #include "ps0920300a.h" ///////////////////////////////////////////////////////////////////////////// // MASCHERA ///////////////////////////////////////////////////////////////////////////// class TPianifica_impianti_mask : public TAutomask { protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: TPianifica_impianti_mask(); virtual ~TPianifica_impianti_mask(); }; TPianifica_impianti_mask::TPianifica_impianti_mask() : TAutomask("ps0920300a") { } TPianifica_impianti_mask::~TPianifica_impianti_mask() { } bool TPianifica_impianti_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { const int id = o.dlg(); switch (id) { case F_ADATA: if (e == fe_modify) { const TDate dadata = get_date(F_DADATA); const int daanno = dadata.year(); const TDate adata = o.get(); const int aanno = adata.year(); if (daanno != aanno) return error_box(TR("Le date devono appartenere allo stesso anno!")); } break; default: break; } return true; } ///////////////////////////////////////////////////////////////// // APPLICAZIONE ///////////////////////////////////////////////////////////////// class TPianifica_impianti : public TSkeleton_application { TPianifica_impianti_mask * _mask; virtual bool check_autorization() const {return false;} virtual const char * extra_modules() const {return "ve";} bool find_my_sister_row(const TRiga_documento& source_row, const TString& a_codnum, const TCodice_articolo& son_codartmag, const TString& a_impianto, TRectype& sister_row, TLog_report& log) const; void delete_old_docs(); void create_new_docs(TLog_report& log); protected: virtual void main_loop(); virtual bool create(); public: const TPianifica_impianti_mask & mask() const {return *_mask;} virtual ~TPianifica_impianti(); }; void TPianifica_impianti::delete_old_docs() { const TDate dadata = _mask->get_date(F_DADATA); const TDate adata = _mask->get_date(F_ADATA); const int anno = dadata.year(); const TString& codnum = _mask->get(F_ANUM); //accoppa i documenti con numerazione di destinazione.. const TString& impianto = _mask->get(F_DAIMP); //..e con l'impianto sorgente! (rompe la supersimmetria) TRelation rel_doc(LF_DOC); TRectype darec(LF_DOC), arec(LF_DOC); TDate dadata_doc = dadata; //solitamente la datadoc precede la datacons di 2 settimane dadata_doc -= 60; darec.put(DOC_DATADOC, dadata_doc); darec.put(DOC_PROVV, "D"); darec.put(DOC_ANNO, anno); darec.put(DOC_CODNUM, codnum); arec.put(DOC_DATADOC, adata); arec.put(DOC_PROVV, "D"); arec.put(DOC_ANNO, anno); arec.put(DOC_CODNUM, codnum); TString filtro; filtro << "CODNUM='" << codnum << "'"; TCursor cur_doc (&rel_doc, filtro, 3, &darec, &arec); const long items = cur_doc.items(); cur_doc.freeze(); TProgind progind(items, "Eliminazione vecchi documenti in corso...", false, true); for (cur_doc = 0; cur_doc.pos() < items; ++cur_doc) { progind.addstatus(1); TDocumento doc(cur_doc.curr()); //trovato un documento che soddisfa il darec/arec deve eliminarlo se la prima riga ha impianto.. //..uguale a quello nel campo F_AIMP sulla maschera bool imp_ok =false, datacons_ok = false; for (int i = 1; i <= doc.physical_rows(); i++) { const TRiga_documento& rigadoc = doc[i]; if (rigadoc.get(RDOC_IMPIANTO) == impianto) imp_ok = true; if (rigadoc.get_date(RDOC_DATACONS) >= dadata) datacons_ok = true; if (imp_ok && datacons_ok) { doc.remove(); break; } } //for(int i =... } //for(cur_doc.. } bool TPianifica_impianti::find_my_sister_row(const TRiga_documento& source_row, const TString& a_codnum, const TCodice_articolo& son_codartmag, const TString& a_impianto, TRectype& sister_row, TLog_report& log) const { TRelation rel_righedoc(LF_RIGHEDOC); TString filtro; filtro << "(CODNUM='" << a_codnum << "')&&"; filtro << "(IMPIANTO='" << a_impianto << "')&&"; filtro << "(CODARTMAG='" << son_codartmag << "')"; TCursor cur_righedoc(&rel_righedoc, filtro, 4, &source_row, &source_row); const long items = cur_righedoc.items(); if (items != 1) { TString errore; if (items == 0) { errore.format("Non ci sono documenti per l'articolo %s", (const char*)son_codartmag); log.log(2, errore); } else { errore.format("Ci sono %ld documenti per l'articolo %s", items, (const char*)son_codartmag); log.log(1, errore); } } if (items > 0) { cur_righedoc = 0; sister_row = cur_righedoc.curr(); } return items > 0; } void TPianifica_impianti::create_new_docs(TLog_report& log) { const TDate dadata = _mask->get_date(F_DADATA); const TDate adata = _mask->get_date(F_ADATA); const int anno = dadata.year(); const TString& da_codnum = _mask->get(F_DANUM); //crea documenti con numerazioni sorgenti... const TString& da_impianto = _mask->get(F_DAIMP); //..con l'impianto sorgente! (conserva la supersimmetria) //questi servono dopo!!! const TString& a_codnum = _mask->get(F_ANUM); const int ritardo = _mask->get_int(F_RITARDO); const TString& a_impianto = _mask->get(F_AIMP); TRelation rel_doc(LF_DOC); TRectype darec(LF_DOC), arec(LF_DOC); TDate dadata_doc = dadata; //solitamente la datadoc precede la datacons di 2 settimane dadata_doc -= 60; darec.put(DOC_DATADOC, dadata_doc); darec.put(DOC_PROVV, "D"); darec.put(DOC_ANNO, anno); darec.put(DOC_CODNUM, da_codnum); arec.put(DOC_DATADOC, adata); arec.put(DOC_PROVV, "D"); arec.put(DOC_ANNO, anno); arec.put(DOC_CODNUM, da_codnum); TString filtro; filtro << "CODNUM='" << da_codnum << "'"; TCursor cur_doc (&rel_doc, filtro, 3, &darec, &arec); const long items = cur_doc.items(); cur_doc.freeze(); TProgind progind(items, "Generazione nuovi documenti in corso...", false, true); TDistinta_tree albero; TRectype sister_row(LF_RIGHEDOC); for (cur_doc = 0; cur_doc.pos() < items; ++cur_doc) { progind.addstatus(1); TDocumento doc(cur_doc.curr()); for (int i = 1; i <= doc.rows(); i++) { const TRiga_documento& source_row = doc[i]; //riga del documento sorgente //il casino va fatto solo se la riga non e' gia' evasa, l'impianto e' quello selezionato e la riga e' riga articolo if (!source_row.is_evasa() && source_row.get(RDOC_IMPIANTO) == da_impianto && source_row.is_articolo()) { const TCodice_articolo father_codartmag = source_row.get(RDOC_CODARTMAG); albero.set_root(father_codartmag); if (albero.goto_firstson()) { TCodice_articolo son_codartmag; albero.curr_code(son_codartmag); //e' risalito al codice dell'articolo figlio //cerca la riga sua sorella, ovvero quella che viene dalla stessa riga ordine mamma originaria if (find_my_sister_row(source_row, a_codnum, son_codartmag, a_impianto, sister_row, log)) { TDate datacons = sister_row.get_date(RDOC_DATACONS); //ignora righe con data consegna fuori dal range selezionato if (datacons < dadata || datacons > adata) continue; datacons += ritardo; const int priority = sister_row.get_int(RDOC_PRIORITY); //crea un documento... TDocumento nuovo_doc('D', anno, a_codnum, 0); nuovo_doc.copy_data(nuovo_doc, doc); nuovo_doc.put(DOC_TIPODOC, a_codnum); //il tipo deve corrispondere alla numerazione! //..e la sua riga vuota TRiga_documento& nuova_rigadoc = nuovo_doc.new_row(source_row.get(RDOC_TIPORIGA)); //riempie la nuova riga nuovo_doc.copy_data(nuova_rigadoc, source_row); nuova_rigadoc.put(RDOC_PRIORITY, priority); nuova_rigadoc.put(RDOC_DATACONS, datacons); //..e alla fine scrive testata e riga!! int err = nuovo_doc.write(); if (err != NOERR) { TString errore; errore.format("Errore %d nella scrittura del documento %ld", err, nuovo_doc.get_long(DOC_NDOC)); log.log(2, errore); } } //if (find_my_sister } //if(albero.goto... } //if(source_row.get... } //for(int i... } //for(cur_doc... } void TPianifica_impianti::main_loop() { while (_mask->run() == K_ENTER) { //intanto accoppa i vecchi documenti di tipo destinazione delete_old_docs(); //poi crea i nuovi documenti di produzione TLog_report log("Errori generazione documenti pianificazione"); create_new_docs(log); TReport_book buc; buc.add(log); buc.preview(); } } bool TPianifica_impianti::create() { open_files(LF_TAB, LF_TABCOM, LF_DOC, LF_RIGHEDOC, LF_DIST, LF_RDIST, LF_ANAMAG, NULL); _mask = new TPianifica_impianti_mask; return TSkeleton_application:: create(); } TPianifica_impianti::~TPianifica_impianti() { delete _mask; } TPianifica_impianti & app() { return (TPianifica_impianti&) main_app();} int ps0920300(int argc, char* argv[]) { TPianifica_impianti a; a.run(argc, argv, "Pianificazione impianti"); return 0; }