#include #include #include #include #include #include "../db/dblib.h" #include "../ve/velib.h" #include "../mr/mrplib.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; TArray _target_dates; 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() { TDate dadata = _mask->get_date(F_DADATA); TDate adata = _mask->get_date(F_ADATA); const int lastday = adata - dadata; const int anno = dadata.year(); const TString& codnum = _mask->get(F_NUM); //accoppa i documenti con numerazione sorgente const TString& impianto = _mask->get(F_AIMP); //..e con l'impianto destinazione TRelation rel_doc(LF_DOC); TRectype darec(LF_DOC), arec(LF_DOC); TDate from(1, 1, anno - 1); TDate to(31, 12, anno); darec.put(DOC_DATADOC, from); darec.put(DOC_PROVV, "D"); darec.put(DOC_ANNO, anno); darec.put(DOC_CODNUM, codnum); arec.put(DOC_DATADOC, to); 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); dadata = (TDate&) _target_dates[0]; adata = (TDate&) _target_dates[lastday]; 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 const TDate h_datacons = doc.get_date(DOC_DATACONS); 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; const TDate datacons = rigadoc.get_date(RDOC_DATACONS); if (datacons.ok()) datacons_ok = (datacons >= dadata) && (datacons <= adata); else datacons_ok = (h_datacons >= dadata) && (h_datacons <= adata); if (imp_ok && datacons_ok) { doc.remove(); break; } } //for(int i =... } //for(cur_doc.. } 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& codnum = _mask->get(F_NUM); //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_impianto = _mask->get(F_AIMP); TRelation rel_doc(LF_DOC); TRectype darec(LF_DOC), arec(LF_DOC); TLocalisamfile db(LF_RDIST); TDate from(1, 1, anno - 1); TDate to(31, 12, anno); db.setkey(2); darec.put(DOC_DATADOC, from); darec.put(DOC_PROVV, "D"); darec.put(DOC_ANNO, anno); darec.put(DOC_CODNUM, codnum); arec.put(DOC_DATADOC, to); arec.put(DOC_PROVV, "D"); arec.put(DOC_ANNO, anno); arec.put(DOC_CODNUM, codnum); TString filtro; TDistinta_tree albero; filtro << "CODNUM='" << 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); for (cur_doc = 0; cur_doc.pos() < items; ++cur_doc) { progind.addstatus(1); TDocumento doc(cur_doc.curr()); TDocumento nuovo_doc('D', anno, codnum, 0); // crea un documento... nuovo_doc.copy_data(nuovo_doc, doc); nuovo_doc.put(DOC_TIPODOC, codnum); //il tipo deve corrispondere alla numerazione! nuovo_doc.put(DOC_STATO, 2); TDate datadoc = nuovo_doc.get(DOC_DATADOC); TDate h_datacons = nuovo_doc.get(DOC_DATACONS); if (h_datacons < dadata || h_datacons > adata) continue; TDate datacons = h_datacons; const int ndays = datacons - dadata; if (ndays > 365) continue; datacons = (TDate &)_target_dates[ndays]; nuovo_doc.put(DOC_DATACONS, datacons); for (int i = 1; i <= doc.rows(); i++) { const TRiga_documento& source_row = doc[i]; //riga del documento sorgente const TString80 codice(source_row.get(RDOC_CODARTMAG)); //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.get(RDOC_IMPIANTO) == da_impianto && source_row.is_articolo()) { db.zero(); db.put("CODCOMP", codice); const int err = db.read(_isgteq); if (err == NOERR && codice == db.get("CODCOMP")) { const TCodice_articolo dest_codart = db.get("CODDIST"); TArray labors; bool found = false; albero.set_root(dest_codart); for (TRiga_esplosione * l = albero.first_labor(labors); l != NULL && !found; l = albero.next_labor(labors)) { TLavorazione * lav = TDistinta_tree::find_labor(l); if (lav != NULL && a_impianto == lav->cod_impianto(0)) { const int priority = source_row.get_int(RDOC_PRIORITY); TDate datacons = source_row.get_date(RDOC_DATACONS); if (!datacons.ok()) datacons = h_datacons; const int ndays = datacons - dadata; datacons = (TDate &)_target_dates[ndays]; if (datacons < dadata || datacons > adata) continue; //..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_CODART, dest_codart); nuova_rigadoc.put(RDOC_CODARTMAG, dest_codart); nuova_rigadoc.put(RDOC_PRIORITY, priority); nuova_rigadoc.zero(nuova_rigadoc.field_qtaevasa()); nuova_rigadoc.zero(RDOC_RIGAEVASA); datacons = source_row.get_date(RDOC_DATACONS); if (datacons.ok()) { datacons = (TDate &)_target_dates[ndays]; nuova_rigadoc.put(RDOC_DATACONS, datacons); } nuova_rigadoc.put(RDOC_IMPIANTO, a_impianto); const TString &linea = lav->cod_linea(0); nuova_rigadoc.put(RDOC_LINEA, linea); found = true; } } } } //if(source_row.get... } //for(int i... if (nuovo_doc.physical_rows() > 0) { 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); } } } //for(cur_doc... } void TPianifica_impianti::main_loop() { while (_mask->run() == K_ENTER) { TDate dadata = _mask->get_date(F_DADATA); TDate adata = _mask->get_date(F_ADATA); TDate data, end_date; const TString8 impianto = _mask->get(F_AIMP); const TString8 linea = _mask->get(F_LIN); TMRP_calendar c(linea, impianto); int ndays = adata - dadata + 1; const int ritardo = _mask->get_int(F_RITARDO); int min, max; data = dadata; end_date = dadata; end_date += ritardo; if (!data.is_holiday() && data.wday() != 6) { c.turni(end_date, min, max); while (max == 0 || end_date.is_holiday() || end_date.wday() == 6) c.turni(++end_date, min, max); } _target_dates.add(end_date, 0); for (int i = 1; i < 366; i++) { data = dadata; data += i; end_date = (TDate &) _target_dates[i - 1]; ++end_date; if (!data.is_holiday() && data.wday() != 6) { c.turni(end_date, min, max); while (max == 0 || end_date.is_holiday() || end_date.wday() == 6) { ++end_date; c.turni(end_date, min, max); } } else if (end_date - data > ritardo) --end_date; _target_dates.add(end_date, i); } delete_old_docs(); //intanto accoppa i vecchi documenti di tipo destinazione //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; }