// gestione tabelle di magazzino #include "mglib.h" #include "../ve/vetbmag.h" #include #include #include #include "mgtbcau.h" #include "mgtbfca.h" #include "mgtbgsa.h" // applicazione per la gestione delle tabelle di magazzino class Tab_app_mag : public TTable_application { protected: // TRelation_application virtual bool user_destroy() ; virtual bool user_create() ; virtual bool protected_record(TRectype& rec) ; virtual int rewrite(const TMask& m); virtual void init_query_mode(TMask& m); virtual TMask * set_mask(TMask * _m=NULL); public: Tab_app_mag(); virtual ~Tab_app_mag() {} }; HIDDEN inline Tab_app_mag& app() { return (Tab_app_mag&)main_app(); } #define MAXMETACH 20 // maschere delle tabelle di magazzino class TMask_tabmag : public TMask { TCodice_livelli * cod_liv; TFile_cache *tab_cache; TMetachar * metach; static bool stdmag_handler(TMask_field &, KEY); // handler static bool singlemag_handler(TMask_field &, KEY); // handler static bool sumsign_handler(TMask_field &, KEY); // handler static bool format_handler(TMask_field &, KEY); // handler dei metacaratteri static bool formatgiac_handler(TMask_field &, KEY); // handler dei metacaratteri static bool codlivart_handler(TMask_field &, KEY); // handler del numero formato articoli static bool codlivgiac_handler(TMask_field &, KEY); // handler del numero formato giacenze static bool codgrp_handler(TMask_field &, KEY); // handler del numero formato static bool adv_codgrp_handler(TMask_field& f, KEY k); // handler codice gruppo avanzato public: // @cmember Disabilita la verifica del modulo in chiave virtual bool check_autorization() const {return FALSE;} TMask_tabmag(const char*, const TString&); virtual ~TMask_tabmag(); }; // costruttore della maschera TMask_tabmag::TMask_tabmag(const char * _maskname, const TString &tabname) : TMask(_maskname) { cod_liv = NULL; if (tabname == "MAG") // Magazzini { TMagazzini magazzini; if (!magazzini.gestmultimag()) { set_handler(F_CODICE, singlemag_handler); set_handler(F_MAGSTD, stdmag_handler); //disable(F_MAGSTD); } if (!magazzini.gestdep()) { field(F_GESTGIA).reset(); field(F_GESTGIA).disable(); } } else if (tabname == "%CAU") { if (!main_app().has_module(DBAUT)) hide(F_DIBAEXPLOSION); set_handler(F_SGNGIAC, sumsign_handler); if (!main_app().has_module(LVAUT)) hide(-LVAUT); } else if (tabname == "FCA") // FORMATO CODICE ARTICOLI { cod_liv=new TCodart_livelli; metach= new TMetachar(""); set_handler(F_FORMLIV, format_handler); set_handler(F_CODLIV, codlivart_handler); } else if (tabname == "GCA") // GRUPPI CODICE ARTICOLI { cod_liv=new TCodart_livelli; set_handler(F_CODGROUP, codgrp_handler); } else if (tabname == "FCG") // FORMATO CODICE GIACENZE { cod_liv = new TCodgiac_livelli; metach = new TMetachar("") ; set_handler(F_FORMLIV, formatgiac_handler); set_handler(F_CODLIV, codlivgiac_handler); } else if (tabname == "GCG") // GRUPPI CODICE GIACENZE { cod_liv = new TCodgiac_livelli; set_handler(F_CODGROUP, codgrp_handler); } else if (tabname == "GSA") // GRUPPI CODICE AVANZATI { set_handler(F_CODGROUP, adv_codgrp_handler); } } TMask_tabmag::~TMask_tabmag() { if (cod_liv!=NULL) delete cod_liv; } // tabella magazzini: controllo codice bool TMask_tabmag::singlemag_handler(TMask_field& f, KEY k) { if (k == K_TAB && f.get().not_empty()) { TTable mag("MAG"); mag.first(); if (!mag.eof() && mag.get("CODTAB")!=f.get()) { f.error_box(TR("E' abilitata la gestione di un solo magazzino")); f.set(mag.get("CODTAB")); } } return TRUE; } // tabella magazzini: controllo mag std bool TMask_tabmag::stdmag_handler(TMask_field& f, KEY k) { if (k == K_ENTER) f.set("X"); return TRUE; } // tabella causali: handler della somma segni bool TMask_tabmag::sumsign_handler(TMask_field& f, KEY k) { bool ok = true; if (k == K_ENTER) { int ss=f.mask().get_int(F_SGNGIAC)-f.mask().get_int(F_SGNRIM); ss-=f.mask().get_int(F_SGNACQ)+f.mask().get_int(F_SGNENTR); ss+=f.mask().get_int(F_SGNVEN)+f.mask().get_int(F_SGNUSC); ss+=f.mask().get_int(F_SGNACL)-f.mask().get_int(F_SGNINCL); ss+=f.mask().get_int(F_SGNPRODF)-f.mask().get_int(F_SGNPRODC); ss+=f.mask().get_int(F_SGNSCAR); f.mask().set(F_SUMSIGN,long(ss)); if (ss!=0) { f.error_box(TR("La somma dei segni \n((GIAC-RIM)-(ACQ+ENTR)+(VEN+USC)+(ACL-INCL)+(PRODF-PRODC) + SCARTI) \ndeve essere uguale a zero")); return FALSE; } #define ABSSALDO(fld) abs(f.mask().get_int(fld)) if (f.mask().edit_mode() || f.mask().insert_mode()) { int ps=ABSSALDO(F_SGNGIAC)+ABSSALDO(F_SGNRIM); ps+=ABSSALDO(F_SGNACQ)+ABSSALDO(F_SGNENTR); ps+=ABSSALDO(F_SGNVEN)+ABSSALDO(F_SGNUSC); ps+=ABSSALDO(F_SGNACL)+ABSSALDO(F_SGNINCL); ps+=ABSSALDO(F_SGNPRODF)+ABSSALDO(F_SGNPRODC); ps+=ABSSALDO(F_SGNORDC)+ABSSALDO(F_SGNORDF); ps+=ABSSALDO(F_SGNLABEL)+ABSSALDO(F_SGNSCAR); if (ps==0) ok = f.yesno_box(TR("Attenzione: la causale non movimenta nessun saldo. Confermare?")); const char tipomov=*f.mask().get(F_TIPOMOV); if ((f.mask().get_int(F_SGNGIAC) >=0 && tipomov=='S') ) ok = f.yesno_box(TR("Attenzione: la causale e' impostata come scarico ma la giacenza non e' movimentata in negativo. Confermare?")); if ((f.mask().get_int(F_SGNGIAC) <=0 && tipomov=='C')) ok = f.yesno_box(TR("Attenzione: la causale e' impostata come carico ma la giacenza non e' movimentata in positivo. Confermare?")); } } return ok; } // HANDLER DEL FORMATO DEL LIVELLO bool TMask_tabmag::format_handler(TMask_field& f, KEY k) { if (k == K_TAB && f.focusdirty()) { TString s(f.get()); TMask_tabmag & mask=((TMask_tabmag &)f.mask()); TTable aux_tabf(app().get_tabname()); s.strip_spaces(); f.set(s); aux_tabf.put("CODTAB",mask.get_int(F_CODLIV)+1); if (aux_tabf.read()==NOERR) { // non è l'ultimo livello: solo caratteri obbligatori if (mask.metach->has_opzchars(s)) { f.error_box(FR("I caratteri di formato opzionali ('%s') sono consentiti solo per l'ultimo livello"), mask.metach->opz_chars()); return FALSE; } } } return TRUE; } // HANDLER DEL FORMATO DEL LIVELLO bool TMask_tabmag::formatgiac_handler(TMask_field& f, KEY k) { if (k == K_TAB && f.focusdirty()) { const int maxlen=15; int total_len=0; TString s(f.get()); TMask_tabmag & mask=((TMask_tabmag &)f.mask()); TTable aux_tabf(app().get_tabname()); s.strip_spaces(); f.set(s); mask.set(F_LENFORM,mask.metach->maxstrlen(s)); aux_tabf.put("CODTAB",1); if (aux_tabf.read()==NOERR) { do { if (aux_tabf.get_int("CODTAB") != mask.get_int(F_CODLIV)) total_len+=aux_tabf.get_int("I0"); } while (aux_tabf.next()==NOERR); } total_len+=mask.get_int(F_LENFORM); if (total_len > maxlen) { f.error_box(FR("La somma delle lunghezze dei codici \n dei livelli di giacenza eccede \nil massimo consentito di %d caratteri"),maxlen); return false; } } return true; } // HANDLER DEL CODICE LIVELLO bool TMask_tabmag::codlivart_handler(TMask_field& f, KEY k) { if (k == K_TAB && f.focusdirty()) { const int codliv=atoi(f.get()); if (codliv>1) // Non è il primo codice { TMask_tabmag & mask=((TMask_tabmag &)f.mask()); TTable aux_tabf(app().get_tabname()); aux_tabf.put("CODTAB",codliv-1); if (aux_tabf.read()==NOERR) // esiste un precedente { TString prevformat(aux_tabf.get("S1")); aux_tabf.put("CODTAB",codliv+1); if (aux_tabf.read()!=NOERR && mask.metach->has_opzchars(prevformat)) return f.error_box(TR("Il livello precedente include caratteri opzionali nel formato\ne non puo' divenire un livello intermedio")); } else return f.error_box(TR("Non si possono inserire salti nel livello del codice")); } } return TRUE; } // HANDLER DEL CODICE GRUPPO AVANZATO bool TMask_tabmag::adv_codgrp_handler(TMask_field& f, KEY k) { if (k == K_TAB && f.focusdirty()) { TMask& m = f.mask(); if (m.query_mode()) { const int desc_pos = m.id2pos(f.dlg()) + 1; TMask_field& desc = m.fld(desc_pos); if (desc.empty()) // Copia il codice nella descrizione se necessario desc.set(f.get()); } } else if (k == K_F8) { TMask& m = f.mask(); if (m.query_mode()) { TString newcod(m.get(F_CODLIV)); const int prlen = newcod.len(); const bool autonumalfa = cache().get("FSA", newcod).get_bool("B1"); newcod << ((TEditable_field&)f).get_window_data(); TString cod(newcod); const int len = cod.len(); TTable gsa("GSA"); cod << (autonumalfa ? "ZZZZZZ" : "999999"); gsa.put("CODTAB", cod); if (gsa.read(_isgteq) != _isemptyfile) { TString code = gsa.get("CODTAB"); if (cod < code.left(len) || (newcod == code.left(len) && !isdigit(code[len]))) { gsa.prev(); code = gsa.get("CODTAB"); } if (newcod == code.left(len)) { if (autonumalfa) { newcod = code; newcod.ltrim(prlen); int add = 1; int lastpos = newcod.len() - 1; while (lastpos >= 0) { newcod[lastpos] += add; if (newcod[lastpos] > '9' && newcod[lastpos] < 'A') { newcod[lastpos] = 'A'; break; } else if (newcod[lastpos] > 'Z') newcod[lastpos--] = '0'; else break; } } else { const int progr = atol(code.mid(len)) + 1; TString fmt; fmt.format("%%s%%0%dld", code.len() - len); newcod.ltrim(prlen); newcod.format(fmt, (const char *)newcod, progr); } f.set(newcod); m.stop_run(K_INS); } } } } return true; } // HANDLER DEL CODICE LIVELLO bool TMask_tabmag::codlivgiac_handler(TMask_field& f, KEY k) { if (k == K_TAB && f.focusdirty()) { const int codliv = atoi(f.get()); if (codliv>1) // Non è il primo codice { TTable aux_tabf(app().get_tabname()); aux_tabf.put("CODTAB",codliv-1); if (aux_tabf.read()!=NOERR) // non esiste un precedente return f.error_box(TR("Non si possono inserire salti nel livello del codice")); } } return TRUE; } // HANDLER DEL CODICE LIVELLO giacenza // HANDLER DEL CODICE LIVELLO anagrafica bool TMask_tabmag::codgrp_handler(TMask_field& f, KEY k) { if ((k == K_TAB && f.focusdirty() )||k == K_ENTER ) { TMask_tabmag & mask=((TMask_tabmag &)f.mask()); if (!mask.cod_liv->enabled()) return f.error_box(TR("Livelli del codice non abilitati")); if (!f.empty() && !(mask.cod_liv->fit_to_format(f.get(),mask.get_int(F_CODLIV)))) return f.error_box(TR("Codice non corrispondente al formato previsto")); } return TRUE; } // costruttore Tab_app_mag::Tab_app_mag() {} bool Tab_app_mag::protected_record(TRectype& rec) { bool prot = rec.get_bool(FPC); if (!prot) { const TString4 tn = get_tabname(); if (tn=="FCA" || tn=="FCG" ) { // non si possono cancellare i livelli intermedi:se non è l'ultimo livello, proteggilo TTable aux_tabf(tn); aux_tabf.put("CODTAB",rec.get_int("CODTAB")+1); if (aux_tabf.read()==NOERR) prot = true; } } return prot; } // alloca/cambia la maschera dell'applicazione TMask * Tab_app_mag::set_mask(TMask * _m) { if (_m != NULL) return Tab_application::set_mask(_m); else { const TString& tabname = get_tabname(); TString maskname; get_mask_name(maskname); return Tab_application::set_mask(new TMask_tabmag(maskname, tabname)); } } bool Tab_app_mag::user_create() { /* la Tab_application::user_create() apre la maschera TMask in modo automatico basandosi sul parametro passato sulla linea di comando e sulla convenzione nome = "BATB"+parametro; ORA: - questa convenzione cambierà per separare i programmi (e le maschere) dei vari pacchetti In tal caso ridefinire il metodo virtual mask_name() - secondo il nuovo stile, gli handler vanno posti in maschere derivate dalla TMask (TMask_tabmag, TMask_tabcau, ecc), pertanto occorre che la maschera aperta sia del tipo corretto per questo motivo la maschera viene creata dalla user_create() */ bool ok = Tab_application::user_create(); if (ok) { //TMask& mask = *set_mask(); } return ok; } bool Tab_app_mag::user_destroy() { return Tab_application::user_destroy(); } int Tab_app_mag::rewrite(const TMask& m) { return Tab_application::rewrite(m); } void Tab_app_mag::init_query_mode(TMask& m) { TTable_application::init_query_mode(m); if (get_tabname() == "GSA" && argc() > 3) m.set(F_CODLIV, argv(3)); } int mg0100(int argc, char* argv[]) { Tab_app_mag a; a.run(argc, argv, TR("Tabella")); return 0; }