#include #include #include #include #include #include "../ve/velib.h" #include "mg0400a.h" #include "clifogiac.h" //--------------------------------------------------- // MASCHERA //--------------------------------------------------- class TClifo_giac_mask : public TMask { TRelation* _rel; // relazione principale TCodgiac_livelli* livelli_giac;// oggetto handler per i livelli di giacenza TCodart_livelli* livelli_art;// oggetto handler per i livelli di anagraficca int last_annogiac; TString4 _um_principale; TMagazzini *_magazzini; static bool notify_sheet_giac(TSheet_field & s, int r, KEY k); // notify delle giacenze static bool handle_sheet_giac_valgiac(TMask_field &, KEY); // handler static bool handle_autoinsert_livgiac(TMask_field &, KEY); // handler del campo static void sheetgiac_get(TSheet_field &fld_righe, int item); static void sheetgiac_put(TSheet_field &fld_righe, int item); public: void set_parametered_fields(); void ricalcola_giacenze(); TCodart_livelli* get_livelli_art() const { return livelli_art; } TMagazzini& magazzini() { return *_magazzini; } TClifo_giac_mask(TRelation * rel); virtual ~TClifo_giac_mask() {} }; bool TClifo_giac_mask::notify_sheet_giac(TSheet_field &f, int i, KEY k) { TClifo_giac_mask & m = (TClifo_giac_mask&)f.mask(); switch (k) { case (K_ENTER): // fine modifica { //controlla che l'indsped di una nuova riga non sia gia' presente, senno' avrebbe 2 record con la stessa.. //..chiave visto che la testata e' uguale per tutti const int indsped = atoi(f.cell(i, f.cid2index(F_INDSPED))); for (int j = 0; j < f.items(); j++) { if (i != j) { const int jndsped = atoi(f.cell(j, f.cid2index(F_INDSPED))); if (indsped == jndsped) return f.error_box(FR("L'indirizzo della riga %d e' lo stesso di quello della riga %d"), i+1, j+1); } } //for (int j = 0... real ck(f.cell(i,f.cid2index(F_RIM))); ck+=real(f.cell(i,f.cid2index(F_ACQ))); ck+=real(f.cell(i,f.cid2index(F_ENTR))); ck-=real(f.cell(i,f.cid2index(F_VEN))); ck-=real(f.cell(i,f.cid2index(F_USC))); ck-=real(f.cell(i,f.cid2index(F_ACL))); ck+=real(f.cell(i,f.cid2index(F_INCL))); ck-=real(f.cell(i,f.cid2index(F_INPRODF))); ck+=real(f.cell(i,f.cid2index(F_INPRODC))); ck-=real(f.cell(i,f.cid2index(F_SCARTI))); ck-=real(f.cell(i,f.cid2index(F_GIAC))); if (!ck.is_zero()) { f.error_box("La giacenza deve essere pari a RIM+(ACQ+ENTR)-(VEN+USC)-(ACL-INCL)-(PRODF-PRODC) - SCARTI)"); return FALSE; } //if(!ck.is_zero())... } break; default: break; } //campi presi da altri campi della maschera per.. //..essere visualizzati nella pag. giacenze if (k == K_TAB) { TMask& sm = f.sheet_mask(); //maschera delle giacenze if (sm.field(F_LIV1).hidden()) //l'articolo appare solo se mancano i livelli di giacenza senno'.. { //..si sovrappongono sm.show(F_CODARTR); sm.show(F_DESCRR); sm.set(F_CODARTR, m.get(F_CODART)); sm.set(F_DESCRR, m.get(F_DESART)); } else { sm.hide(F_CODARTR); sm.hide(F_DESCRR); } } return true; } bool TClifo_giac_mask::handle_sheet_giac_valgiac(TMask_field &f, KEY k) { if (k == K_TAB && f.dirty()) { TMask& m = f.mask(); real q=m.get_real(F_RIM)+m.get_real(F_ACQ); if (q.is_zero()) f.set(q.string()); else { q=(m.get_real(F_VRIM)+m.get_real(F_VACQ))/q; TPrice r(q); f.set(r.get_num().string()); } } return true; } bool TClifo_giac_mask::handle_autoinsert_livgiac(TMask_field &fld, KEY k) { if (k == K_TAB && fld.focusdirty() && !fld.empty()) { TClifo_giac_mask & mask = (TClifo_giac_mask&)fld.mask().get_sheet()->mask(); const int levnum = fld.dlg() - F_LIV1 + 1; return mask.livelli_giac->autoinsert(levnum, fld); } return true; } void TClifo_giac_mask::sheetgiac_get(TSheet_field &fld_righe, int item) { TClifo_giac_mask &m = (TClifo_giac_mask&)fld_righe.mask(); // prende il record della riga corrente dal record array TRectype &rec = fld_righe.record()->row(item, TRUE); TToken_string &row = fld_righe.row(item-1); // codici di livello row.add( m.livelli_giac->unpack_grpcode(rec.get("LIVELLO") ,1),fld_righe.cid2index(F_LIV1) ); row.add( m.livelli_giac->unpack_grpcode(rec.get("LIVELLO") ,2),fld_righe.cid2index(F_LIV2) ); row.add( m.livelli_giac->unpack_grpcode(rec.get("LIVELLO") ,3),fld_righe.cid2index(F_LIV3) ); row.add( m.livelli_giac->unpack_grpcode(rec.get("LIVELLO") ,4),fld_righe.cid2index(F_LIV4) ); } // item varies from 1 to items() void TClifo_giac_mask::sheetgiac_put(TSheet_field &fld_righe, int item) { TClifo_giac_mask &m = (TClifo_giac_mask&)fld_righe.mask(); TToken_string &row= fld_righe.row(item - 1); TRectype &recrighe= fld_righe.record()->row(item, TRUE); // codici livello if (m.livelli_giac->enabled()) { TString16 packedcode; m.livelli_giac->pack_grpcode(packedcode,row.get(fld_righe.cid2index(F_LIV1)),1); m.livelli_giac->pack_grpcode(packedcode,row.get(fld_righe.cid2index(F_LIV2)),2); m.livelli_giac->pack_grpcode(packedcode,row.get(fld_righe.cid2index(F_LIV3)),3); m.livelli_giac->pack_grpcode(packedcode,row.get(fld_righe.cid2index(F_LIV4)),4); recrighe.put("LIVELLO", packedcode); } } void TClifo_giac_mask::set_parametered_fields() { // abilitazioni parametriche if (livelli_giac) delete livelli_giac; if (livelli_art) delete livelli_art; if (_magazzini) delete _magazzini; _magazzini = new TMagazzini; // imposta il puntatore al gestore livelli giacenze livelli_giac= new TCodgiac_livelli(); livelli_art= new TCodart_livelli(); // imposta il valore dell'anno per le giacenze last_annogiac = -1; // Abilita la pagina delle giacenze const bool gestmag = main_app().has_module(MGAUT) && magazzini().gestmag(); // sheet giacenze TSheet_field& sgiac = sfield(F_SHEETGIAC); sgiac.set_userget(sheetgiac_get); sgiac.set_userput(sheetgiac_put); sgiac.sheet_mask().set_handler(F_VALGIAC, handle_sheet_giac_valgiac); // setta i campi della maschera per la pagina giacenze TSheet_field &fld_giac = sfield(F_SHEETGIAC); fld_giac.set_notify(notify_sheet_giac); // disabilita le colonne quando non sono utilizzati i livelli di giacenza for (int i = 0; i < 4; i++) { livelli_giac->set_sheetcolumn(fld_giac,F_LIV1+i,i+1); if (livelli_giac->autoinsert(i+1)) { // codice autoinseribile TMask_field & campo_liv = fld_giac.sheet_mask().field(F_LIV1+i); campo_liv.check_type(CHECK_SEARCH); campo_liv.set_handler(gestmag ? handle_autoinsert_livgiac : NULL); } } // abilita la gestione delle ubicazioni (manuale/su tabella) if (magazzini().gestubi_man()) { fld_giac.sheet_mask().field(F_UBICAZ).check_type(CHECK_SEARCH); fld_giac.sheet_mask().field(F_UBICAZD).check_type(CHECK_SEARCH); } } // costruttore della maschera anagrafica di magazzino TClifo_giac_mask::TClifo_giac_mask(TRelation * rel) : TMask("mg0400a") { _rel = rel; livelli_giac = NULL; livelli_art = NULL; _magazzini = NULL; set_parametered_fields(); } //--------------------------------------------------------------------------------------------------------------------------// //-------------------------------------------- // APPLICAZIONE //-------------------------------------------- class TClifo_giac : public TRelation_application { TClifo_giac_mask *_msk; // maschera principale TRelation *_rel; // relazione principale di un solo file clifogiac protected: virtual bool user_create(); virtual bool user_destroy(); virtual TMask *get_mask(int) { return _msk; } TString query_giacenze(const TMask& m); virtual int read(TMask& m); virtual bool find(word key = 0); void fill_giacenze(const TMask& m); virtual bool remove(); int remove_giacenze(const char tipocf, const long codcf, const TString& codart, const int annoes); virtual int write(const TMask& m); virtual int rewrite(const TMask& m); int find_codindsp(TSheet_field& s,const int codindsp) const; int write_giacenze(const TMask& m); public: virtual TRelation *get_relation() const { return _rel; } TClifo_giac() { _rel = NULL; _msk = NULL;} virtual ~TClifo_giac() {} }; //----------------------------------------------------------------------------- // Metodo comune per riempire una stringa da usare come query nei vari recset //----------------------------------------------------------------------------- TString TClifo_giac::query_giacenze(const TMask& m) { const char tipocf = m.get(F_TIPOCF)[0]; const long codcf = m.get_long(F_CODCF); const TString80 codart = m.get(F_CODART); const int annoes = m.get_int(F_ANNOES); TString& giacenze = get_tmp_string(); giacenze << "USE CLIFOGIAC KEY 3\n" << "\nFROM ANNOES=" << annoes << " CODART=" << codart << " TIPOCF=" << tipocf << " CODCF=" << codcf << "\nTO ANNOES=" << annoes << " CODART=" << codart << " TIPOCF=" << tipocf << " CODCF=" << codcf ; return giacenze; } //------------------ // Metodi READ //------------------ //FILL_GIACENZE: metodo x riempire lo sheet della maschera con tutti i record che soddisfano la chiave incompleta void TClifo_giac::fill_giacenze(const TMask& m) { TISAM_recordset giacenze(query_giacenze(m)); int items = giacenze.items(); //riempie lo sheet con i record che soddisfano la chiave parziale applicata per avere il recordset TSheet_field& sheet = m.sfield(F_SHEETGIAC); TMask& sheetmask = sheet.sheet_mask(); TRelation& rel = *giacenze.cursor()->relation(); //accesso alle righe sheet.destroy(); if (giacenze.items() > 0) { for (bool ok = giacenze.move_first(); ok; ok = giacenze.move_next()) { TToken_string& row = sheet.row(-1); //crea una nuova riga dello sheet //scandisco nella maschera tutti i campi che hanno un field FOR_EACH_MASK_FIELD(sheetmask, i, f) { const TFieldref* fr = f->field(); //leggo il valore dalla relation if (fr != NULL) row.add(fr->read(rel),sheet.cid2index(f->dlg())); //metto il valore letto nella posizione corretta nella TToken_string } sheet.check_row(sheet.items()-1); //fa fare alla maschera la decodifica dei codici e aggiorna la TToken_string } sheet.force_update(); //forza l'update dello sheet, in modo da rendere visibili i cambiamenti fatti } return; } bool TClifo_giac::find(word key) { bool ok = false; const char tipocf = _msk->get(F_TIPOCF)[0]; const long codcf = _msk->get_long(F_CODCF); const TString80 codart = _msk->get(F_CODART); const int annoes = _msk->get_int(F_ANNOES); TLocalisamfile clifogiac(LF_CLIFOGIAC); clifogiac.put(CLIFOGIAC_ANNOES, annoes); clifogiac.put(CLIFOGIAC_CODART, codart); clifogiac.put(CLIFOGIAC_TIPOCF, tipocf); clifogiac.put(CLIFOGIAC_CODCF, codcf); clifogiac.setkey(3); ok = clifogiac.read(_isgteq) == NOERR; return ok; } int TClifo_giac::read(TMask& m) { fill_giacenze(m); return NOERR; } //------------------ // Metodi WRITE //------------------ int TClifo_giac::find_codindsp(TSheet_field& s,const int codindsp) const { int r=-1; //per ogni riga dello sheet, legge codindsp, //e se esiste interrompe restituendo un valore positivo, //se no arriva fino in fondo e resituisci -1 for (r = s.items()-1; r >= 0; r--) { const int indsped = s.row(r).get_int(s.cid2index(F_INDSPED)); if (codindsp == indsped) break; } return r; } //WRITE_GIACENZE:scrive i dati sul file 166 (CLIFOGIAC) int TClifo_giac::write_giacenze(const TMask& m) { TISAM_recordset giacenze(query_giacenze(m)); int err = NOERR; TLocalisamfile& clifogiac = giacenze.cursor()->file(); //si prende lo sheet sulla maschera principale... TSheet_field& sheet_giac = m.sfield(F_SHEETGIAC); //per ogni riga del recordset for (bool ok = giacenze.move_first(); ok; ok = giacenze.move_next()) { //leggo indirizzo spedizione unico campo chiave sulla riga dello sheet const int codindsp = giacenze.get(CLIFOGIAC_INDSPED).as_int(); //tutte le righe del TISAM_recordset che NON SONO nel TRecord_array vanno eliminate dal file if (find_codindsp(sheet_giac, codindsp) < 0) clifogiac.remove(); } //prende i dati dalla maschera principale const char tipocf = m.get(F_TIPOCF)[0]; const long codcf = m.get_long(F_CODCF); const TString80 codart = m.get(F_CODART); const int annoes = m.get_int(F_ANNOES); //..e quindi la maschera di sheet TMask& msk = sheet_giac.sheet_mask(); //per ogni riga dello sheet FOR_EACH_SHEET_ROW(sheet_giac, r, row) { clifogiac.zero(); //dati comuni a tutte le righe dello sheet clifogiac.put(CLIFOGIAC_TIPOCF, tipocf); clifogiac.put(CLIFOGIAC_CODCF, codcf); clifogiac.put(CLIFOGIAC_ANNOES, annoes); clifogiac.put(CLIFOGIAC_CODART, codart); //per ogno campo della maschera di sheet FOR_EACH_MASK_FIELD(msk, i, f) { //prendo il FIELD a cui si riferiscono const TFieldref*fr = f->field(); //se efftivamente il campo ha un field di riferimento if (fr != NULL) { const int pos = sheet_giac.cid2index(f->dlg()); //salvo la sua posizione all'inetrno dello sheet fr->write(row->get(pos), clifogiac.curr()); //scrivo il valore che sto leggendo nel record corrente del file } } //o faccio la rewrite, o faccio la write err = clifogiac.rewrite_write(); } return err; } int TClifo_giac::write(const TMask& m) { return write_giacenze(m); } int TClifo_giac::rewrite(const TMask& m) { return write_giacenze(m); } //------------------ // Metodi REMOVE //------------------ //REMOVE_GIACENZE: elimina tutte le righe dello sheet per il clifo,l'articolo e l'anno passati int TClifo_giac::remove_giacenze(const char tipocf, const long codcf, const TString& codart, const int annoes) { TString query_giacenze; query_giacenze << "USE CLIFOGIAC KEY 3\n" << "\nFROM ANNOES=" << annoes << " CODART=" << codart << " TIPOCF=" << tipocf << " CODCF=" << codcf << "\nTO ANNOES=" << annoes << " CODART=" << codart << " TIPOCF=" << tipocf << " CODCF=" << codcf ; TISAM_recordset giacenze(query_giacenze); int err = NOERR; //l'accoppamento delle righe va fatto proprio sul file, quindi sotto con il localisamfile.. TLocalisamfile& clifogiac = giacenze.cursor()->file(); //per ogni riga del recordset for (bool ok = giacenze.move_first(); ok; ok = giacenze.move_next()) { err = clifogiac.remove(); } return err; } bool TClifo_giac::remove() { //recupero i dati della testata const TRectype rec = _rel->curr(); const char tipocf = rec.get_char(CLIFOGIAC_TIPOCF); const long codcf = rec.get_long(CLIFOGIAC_CODCF); const TString80 codart = rec.get(CLIFOGIAC_CODART); const int annoes = rec.get_int(CLIFOGIAC_ANNOES); return remove_giacenze(tipocf, codcf, codart, annoes) > 0; } //--------------------- // Metodi GENERICI //--------------------- bool TClifo_giac::user_create() { _rel = new TRelation(LF_CLIFOGIAC); _msk = new TClifo_giac_mask(_rel); const bool gestmag = _msk->magazzini().gestmag(); if (!gestmag) { return error_box(TR("Per utilizzare questo programma e' NECESSARIO attivare la Gestione del magazzino!")); } return true; } bool TClifo_giac::user_destroy() { delete _rel; delete _msk; return true; } int mg0400(int argc, char* argv[]) { TClifo_giac a; a.run(argc, argv, "Giacenze per Clienti/Fornitori"); return 0; }