#include #include #include #include #include #include #include #include #include <../mg/rmovmag.h> #include <../ve/velib.h> #include "halib.h" #include "ha3800a.h" ////////////////////////////////////////////// // Maschera ////////////////////////////////////////////// class TInserimento_storico_mask : public TAutomask { protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); public: TInserimento_storico_mask(); }; bool TInserimento_storico_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case F_ANNO: if (e == fe_modify) { //cambiando l'anno propone in automatico il dadata adata const int anno = o.get_long(); const TDate ini_anno(1, 1, anno); set(F_DADATA, ini_anno); const TDate fine_anno(31, 12, anno); set(F_ADATA, fine_anno); } break; case F_DADATA: case F_ADATA: if (e == fe_modify || e == fe_close) { //controlla che le date appartengano all'anno selezionato (e impedisce di lasciare date vuote!!!) const TDate data = get_date(o.dlg()); const int anno = get_int(F_ANNO); if (data.year() != anno) return error_box("La data deve appartenere all'anno selezionato!"); } break; default: break; } return true; } TInserimento_storico_mask::TInserimento_storico_mask() : TAutomask("ha3800a") { } ////////////////////////////////////////////// // Applicazione ////////////////////////////////////////////// class TInserimento_storico : public TSkeleton_application { // bool ultimo_cliente_aperto(TRecordset& history, long& clifo, long& indsped) const; protected: void elabora_chiusura(const TRecordset& mov_recset, TLog_report& log) const; void elabora_apertura(const TRecordset& mov_recset, TLog_report& log) const; void elabora(const TMask& mask); public: virtual void main_loop(); }; void TInserimento_storico::elabora_apertura(const TRecordset& mov_recset, TLog_report& log) const { const TString8 causape = mov_recset.get(MOVMAG_CODCAUS).as_string(); //comunque deve scrivere il cliente e la data perchè è un'apertura quindi la macchina è assegnata.. //..al cliente con questo documento const long doc_ndoc = mov_recset.get(MOVMAG_NUMREG).as_int(); const TDate doc_datadoc = mov_recset.get(MOVMAG_DATAREG).as_date(); const long doc_anno = doc_datadoc.year(); const long doc_clifo = mov_recset.get(MOVMAG_CODCF).as_int(); const long indsped = mov_recset.get(MOVMAG_CODINDSP).as_int(); TToken_string key; key << mov_recset.get(MOVMAG_NUMREG); TRecord_array rmovmag(key, LF_RMOVMAG); for (int r = 1; r > 0 && r <= rmovmag.last_row(); r++) { const TRectype& row = rmovmag.row(r); //controllo della causale const TString8 caus = row.get(RMOVMAG_CODCAUS); //se la causale non è sulla riga controlla quella di testata if (caus.full() && caus != causape) continue; //3_A) tabella &ATT //poichè documento apertura deve controllare se per caso la macchina è nuova //dati del record corrente (vale anche per le chiusure in quanto esistono macchine.. //..di antica data senza registrazioni!) const TString80 codart = row.get(RMOVMAG_CODART); const TString16 matricola = row.get(RMOVMAG_LIVGIAC); TModule_table tab_att("&ATT"); tab_att.put("CODTAB", matricola); const int err = tab_att.read(); //se l'attrezzatura (intesa come codart+matricola) non esiste -> la deve aggiungere (sara' sicuramente la prima)... //..per quanto riguarda il progressivo) if (err != NOERR) { TString msg; msg << "Articolo " << codart << " senza matricola sul movimento " << mov_recset.get(MOVMAG_NUMREG) << " del " << mov_recset.get(MOVMAG_DATAREG); log.log(1, msg); continue; } //se la macchina viene assegnata ad un cliente (movimento di apertura) -> va messo il clifo.. tab_att.put("I0", doc_clifo); tab_att.put("I1", indsped); tab_att.put("D0", doc_datadoc); tab_att.write_rewrite(); //3_B) tabella &HIS //controllo sul ndoc se per caso questa riga l'ha già importata, senno' deve aggiungere un record //query sulla storia di questa macchina TString query_his; query_his << "USE &HIS"; query_his << "\nFROM CODTAB=#CODTAB"; query_his << "\nTO CODTAB=#CODTAB"; TISAM_recordset recset_his(query_his); recset_his.set_var("#CODTAB", matricola); const long recset_his_items = recset_his.items(); TModule_table tab_his("&HIS"); int n_line_to_update = 0; //cerca se la riga esiste già nello storico e va solo aggiornata for (bool ok = recset_his.move_last(); ok; ok = recset_his.move_prev()) { const long curr_anno = recset_his.get("S4[1,4]").as_int(); if (curr_anno == doc_anno) { long curr_ndoc = recset_his.get("S4[9,15]").as_int(); if (curr_ndoc == doc_ndoc) { n_line_to_update = recset_his.get("CODTAB[9,13]").as_int(); break; } } } //for (bool ok = recset_his.move... TString80 new_codtab; //se la riga non c'era -> va aggiunta if (n_line_to_update <= 0) { n_line_to_update = recset_his_items + 1; //adesso ha il numero di riga da aggiornare e crea il nuovo record new_codtab.format("%08s%05d", (const char*)matricola, n_line_to_update); tab_his.put("CODTAB", new_codtab); tab_his.write(); new_codtab.cut(0); } //rimette il codtab per riposizionarsi sul record corretto new_codtab.format("%08s%05d", (const char*)matricola, n_line_to_update); tab_his.put("CODTAB", new_codtab); //ed aggiunge tutti i campi const TString& descr = mov_recset.get(MOVMAG_DESCR).as_string(); tab_his.put("S0", descr); //tab_his.put("S3", articolo_collegato); TString16 str_key_doc; str_key_doc.format("%4d%4s%7d", doc_anno, (const char*)causape, doc_ndoc); tab_his.put("S4", str_key_doc); tab_his.put("S6", row.get(RMOVMAG_UM)); const TString& codmag = row.get(RMOVMAG_CODMAG); TString4 s7; //s7[1,1]=tipo s7[2,4]=codmag s7 << "C" << codmag; tab_his.put("S7", s7); tab_his.put("I0", doc_clifo); tab_his.put("I1", indsped); tab_his.put("D0", doc_datadoc); const real qta = row.get(RMOVMAG_QUANT); tab_his.put("R0", qta); const real prezzo = row.get(RMOVMAG_PREZZO); const real importo = qta * prezzo; tab_his.put("R1", importo); tab_his.put("B0", false); const int written = tab_his.write_rewrite(); //segna sul log la riga aggiunta alla tabella storico &HIS if (written == NOERR) { TString msg; msg.format("%4d-%4s/%7d--%s--%s--%6d", doc_anno, (const char*)causape, doc_ndoc, (const char*)codart, (const char*)matricola, doc_clifo); log.log(0, msg); } } } /* Obsoleto bool TInserimento_storico::ultimo_cliente_aperto(TRecordset& recset, long& clifo, long& indsped) const { clifo = indsped = 0; TString_array aperture; TString_array chiusure; TString80 tok; long cli, ind, dat; for (bool ok = recset.move_first(); ok; ok = recset.move_next()) { const bool chiusura = recset.get("B0").as_bool(); cli = recset.get("I0").as_int(); ind = recset.get("I1").as_int(); dat = recset.get("D0").as_date().date2ansi(); tok.format("%ld|%ld|%ld", cli, ind, dat); if (chiusura) chiusure.add(tok); else aperture.add(tok); } FOR_EACH_ARRAY_ROW(aperture, a, ape) { ape->get(0, cli); ape->get(1, ind); ape->get(2, dat); bool found = false; FOR_EACH_ARRAY_ROW(chiusure, c, chi) { long c, i, d; chi->get(0, c); chi->get(1, i); chi->get(2, d); if (cli == c && ind == i && d >= dat) { found = true; break; } } if (!found) { clifo = cli; indsped = ind; break; } } return clifo > 0; } */ void TInserimento_storico::elabora_chiusura(const TRecordset& mov_recset, TLog_report& log) const { const TDate mov_datareg = mov_recset.get(MOVMAG_DATAREG).as_date(); const int anno = mov_datareg.year(); const long mov_nreg = mov_recset.get(MOVMAG_NUMREG).as_int(); const TString8 caus_close = mov_recset.get(MOVMAG_CODCAUS).as_string(); TToken_string key; key << mov_recset.get(MOVMAG_NUMREG); TRecord_array rmovmag(key, LF_RMOVMAG); for (int r = 1; r > 0 && r <= rmovmag.last_row(); r++) { const TRectype& row = rmovmag.row(r); //controllo della causale di riga se diversa dalla testata const TString& caus = row.get(RMOVMAG_CODCAUS); if (caus.full() && caus != caus_close) continue; const TString80 codart = row.get(RMOVMAG_CODART); const TString16 matricola = row.get(RMOVMAG_LIVGIAC); TModule_table tab_att("&ATT"); tab_att.put("CODTAB", matricola); const int err = tab_att.read(); if (err != NOERR) { TString msg; msg << "Articolo " << codart << " senza matricola sul movimento " << mov_nreg << " del " << mov_datareg; log.log(1, msg); continue; } long clifo = 0, indsped = 0; if (tab_att.get_date("D0") <= mov_datareg) { clifo = tab_att.get_long("I0"); indsped = tab_att.get_int("I1"); } TString query_his; query_his << "USE &HIS SELECT S7[1,1]='C'"; query_his << "\nFROM CODTAB=#CODTAB"; query_his << "\nTO CODTAB=#CODTAB"; TISAM_recordset recset_his(query_his); recset_his.set_var("#CODTAB", matricola); int n_line_to_update = 0; const long recset_his_items = recset_his.items(); if (recset_his_items > 0) { //cerca se la riga esiste già nello storico e va solo aggiornata for (bool ok = recset_his.move_last(); ok; ok = recset_his.move_prev()) { const long curr_anno = recset_his.get("S5[1,4]").as_int(); const long curr_nreg = recset_his.get("S5[9,15]").as_int(); if (curr_anno == anno && curr_nreg == mov_nreg) { n_line_to_update = recset_his.get("CODTAB[9,13]").as_int(); clifo = recset_his.get("I0").as_int(); indsped = recset_his.get("I1").as_int(); break; } } //for (bool ok = recset_his.move... //se la riga non c'era -> va aggiunta } if (n_line_to_update <= 0) n_line_to_update = recset_his_items + 1; TModule_table tab_his("&HIS"); TString16 new_codtab; new_codtab.format("%08s%05d", (const char*)matricola, n_line_to_update); tab_his.put("CODTAB", new_codtab); //ed aggiunge tutti i campi const TString& descr = mov_recset.get(MOVMAG_DESCR).as_string(); tab_his.put("S0", descr); TString16 str_key_doc; str_key_doc.format("%4d%4s%7d", anno, (const char*)caus_close, mov_nreg); tab_his.put("S5", str_key_doc); tab_his.put("S6", row.get(RMOVMAG_UM)); const TString& codmag = row.get(RMOVMAG_CODMAG); TString4 s7; //s7[1,1]=tipo s7[2,4]=codmag s7 << "C" << codmag; tab_his.put("S7", s7); tab_his.put("I0", clifo); tab_his.put("I1", indsped); tab_his.put("D0", mov_datareg); const real qta = row.get(RMOVMAG_QUANT); tab_his.put("R0", qta); const real prezzo = row.get(RMOVMAG_PREZZO); const real importo = qta * prezzo; tab_his.put("R1", importo); tab_his.put("B0", true); // Chiusura const int written = tab_his.write_rewrite(); //segna sul log la riga aggiunta alla tabella storico &HIS if (written == NOERR) { TString msg; msg.format("%4d-%4s/%7d--%s--%s--%6d", anno, (const char*)caus_close, mov_nreg, (const char*)codart, (const char*)matricola, clifo); log.log(0, msg); } if (tab_att.get_long("I0") == clifo && tab_att.get_long("I1") == indsped && tab_att.get_date("D0") <= mov_datareg) { tab_att.put("I0", ""); // Azzera cliente tab_att.put("I1", ""); // Azzera indsped tab_att.put("D0", mov_datareg); tab_att.write_rewrite(); } } } void TInserimento_storico::elabora(const TMask& mask) { TConfig config(CONFIG_DITTA, "ha"); const TString8 caus_open = config.get("CausOpen"); const TString8 caus_close = config.get("CausClose"); // Vogliono pure il log! TLog_report log(TR("Righe storico aggiunte")); log.kill_duplicates(); log.log(0, ""); log.log(0, HR("Anno-Num.-Ndoc--Articolo --Matricola --Cliente")); log.log(0, ""); const long anno = mask.get_long(F_ANNO); const TDate da_data = mask.get_date(F_DADATA); const TDate a_data = mask.get_date(F_ADATA); TString query; query << "USE MOVMAG KEY 3" << "\nFROM DATAREG=#DADATA" << "\nTO DATAREG=#ADATA"; TISAM_recordset mov_recset(query); mov_recset.set_var("#DADATA", da_data); mov_recset.set_var("#ADATA", a_data); for (bool ok = mov_recset.move_first(); ok; ok = mov_recset.move_next()) { const TString& codcaus = mov_recset.get(MOVMAG_CODCAUS).as_string(); if (codcaus == caus_open) elabora_apertura(mov_recset, log); else if (codcaus == caus_close) elabora_chiusura(mov_recset, log); } log.preview(); } void TInserimento_storico::main_loop() { TInserimento_storico_mask mask; while (mask.run() == K_ENTER) elabora(mask); } int ha3800(int argc, char* argv[]) { TInserimento_storico app; app.run(argc, argv, TR("Inserimento storico attrezzature")); return 0; }