#include #include #include #include #include #include #include #include #include "..\mg\mglib.h" //#include "..\cg\cglib.h" #include "..\ve\veconf.h" #include "mg1100.h" #ifndef __DBLIB_H #include "..\db\dblib.h" #endif //******************** //******************** // maschera dell'applicazione "Gestione interattiva movimenti di magazzino" // class TMask_movmag: public TMask { static TRecord_cache cache_causali; TMov_mag * mov_mag; TCodgiac_livelli * livelli_giac; // oggetto gestione livelli di giacenza TString price_codart; real price_quant; bool price_proposed; real proposed_price(const char * codart, real quant,const char * causrig); // aggiorna la riga di magazzino aggiungendo righe automatiche o esplosioni bool update_rigamov (int r, const char * old_codcaus, const char * old_codart, const real & old_quant); bool add_autorows (int r, const char * old_codcaus, const char * old_codart, const real & old_quant); bool add_explrows (int r); TMagazzini _magazzini; static bool notify_righe(TSheet_field & fld_righe, int item, KEY k); // notify delle righe di sheet static bool handle_righe(TMask_field &f, KEY k); // handler delle righe static bool handle_righeprezzo1(TMask_field &f, KEY k); // handler del prezzo delle righe static bool handle_righeprezzo2(TMask_field &f, KEY k); // handler del prezzo delle righe static bool handle_codcaus(TMask_field &fld, KEY k); // handler della causale static bool handle_datacomp(TMask_field &, KEY k); // handler del numero di registrazione static void sheetrighe_put(TSheet_field &fld_righe, int item); static void sheetrighe_get(TSheet_field &fld_righe, int item); public: const TMagazzini & magazzini() const {return _magazzini;} TMask_movmag(TCodgiac_livelli *l_m,TMov_mag * m_m); virtual ~TMask_movmag(); }; TRecord_cache TMask_movmag::cache_causali("%CAU"); // costruttore della maschera anagrafica di magazzino //TMask_movmag::TMask_movmag() : TMask_movmag::TMask_movmag(TCodgiac_livelli *l_m,TMov_mag * m_m) : TMask("mg1100") { // oggetti dell'applicazione livelli_giac= l_m; mov_mag = m_m; // setta handler e notify TSheet_field & ss=(TSheet_field &)field(F_RIGHE); set_handler(F_DATACOMP, handle_datacomp); set_handler(F_CODCAUS, handle_codcaus); ss.sheet_mask().field(F_QUANT).set_handler(handle_righeprezzo1); ss.sheet_mask().field(F_CAUSRIG).set_handler(handle_righeprezzo1); ss.sheet_mask().field(F_CODART).set_handler(handle_righeprezzo2); ss.set_notify(notify_righe); ss.set_handler(handle_righe); ss.set_userget(sheetrighe_get); ss.set_userput(sheetrighe_put); ss.set_lines_record(m_m->body()); // setta i campi della maschera // per la pagina giacenze TSheet_field &fld_righe= (TSheet_field &)field(F_RIGHE); // setta le colonne in base all'abilitazione dei livelli di giacenza livelli_giac->set_sheetcolumn(fld_righe,F_LIV1,1); livelli_giac->set_sheetcolumn(fld_righe,F_LIV2,2); livelli_giac->set_sheetcolumn(fld_righe,F_LIV3,3); livelli_giac->set_sheetcolumn(fld_righe,F_LIV4,4); TConfig prassid(CONFIG_DITTA, "ve"); // apre il file di configurazione della ditta corrente if (prassid.get_bool("GES", NULL, A_LISTINI)) field(F_CATVEN).show(prassid.get_bool("GESLISCV")); else field(F_CATVEN).hide(); ss.sheet_mask().field(F_DESMAG).enable(magazzini().gestmultimag()); ss.enable_column(ss.cid2index(F_CODMAG),magazzini().gestmultimag()); } TMask_movmag::~TMask_movmag() { } // item varies from 1 to items() void TMask_movmag::sheetrighe_get(TSheet_field &fld_righe, int item) { TMask_movmag &m=(TMask_movmag &)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("LIVGIAC") ,1),fld_righe.cid2index(F_LIV1) ); row.add( m.livelli_giac->unpack_grpcode(rec.get("LIVGIAC") ,2),fld_righe.cid2index(F_LIV2) ); row.add( m.livelli_giac->unpack_grpcode(rec.get("LIVGIAC") ,3),fld_righe.cid2index(F_LIV3) ); row.add( m.livelli_giac->unpack_grpcode(rec.get("LIVGIAC") ,4),fld_righe.cid2index(F_LIV4) ); } // item varies from 1 to items() void TMask_movmag::sheetrighe_put(TSheet_field &fld_righe, int item) { TMask_movmag &m=(TMask_movmag &)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("LIVGIAC", packedcode); } } bool TMask_movmag::handle_righe(TMask_field &f, KEY k) { if (k == K_ENTER) { TSheet_field& ss=(TSheet_field & )f; const int column = ss.cid2index(F_CODMAG); if (ss.column_enabled(column)) { for (int i = 0; i < ss.items(); i++) { if (*ss.cell(i,column) <= ' ') { f.error_box("Nella riga %d manca l'indicazione del magazzino ",i+1); return FALSE; } } } } return TRUE; } bool TMask_movmag::notify_righe(TSheet_field & ss, int r, KEY key) { TMask_movmag &m=(TMask_movmag &)ss.mask(); static TString16 old_codcaus; static TString old_codart(20); static real old_quant(1); if ( key == K_DEL ) // Cancellazione { if (*ss.cell(r,ss.cid2index( F_AUTOMATICA))==riga_automatica) return FALSE; // can't remove auto lines directly while (r < ss.items()-1 && *ss.cell(r+1,ss.cid2index( F_AUTOMATICA))==riga_automatica) { // autoremove automatic lines along with the original one ss.destroy(r+1); } } else if (key == K_INS) { // Inserimento if (r < ss.items() && *ss.cell(r,ss.cid2index( F_AUTOMATICA))==riga_automatica) return FALSE; // cannot insert between a row and its generated one } else if (key == K_CTRL + K_INS) { // Inserimento accordato if (m.magazzini().standardmag().not_empty()) { ss.row(r).add(m.magazzini().standardmag(),ss.cid2index(F_CODMAG)); ss.row(r).add(m.magazzini().standarddep(),ss.cid2index(F_CODDEP)); } ss.select(r); } else if (key == K_SPACE) { old_codcaus=ss.sheet_mask().get(F_CAUSRIG); if (old_codcaus.blank()) old_codcaus=ss.mask().get(F_CODCAUS); old_quant=ss.sheet_mask().get_real(F_QUANT); old_codart=ss.sheet_mask().get(F_CODART); } else if (key == K_ENTER) { if (m.update_rigamov(r,old_codcaus,old_codart,old_quant)) ss.select(r+1); } return TRUE; } // proposta soft: solo se il prezzo è non nullo (già impostato) bool TMask_movmag::handle_righeprezzo1(TMask_field &f, KEY k) { if (f.mask().get(F_PREZZO).blank()) return handle_righeprezzo2(f, k); return TRUE; } // proposta hard: propone il prezzo in ogni caso bool TMask_movmag::handle_righeprezzo2(TMask_field &f, KEY k) { TMask_movmag &m=(TMask_movmag &)f.mask().get_sheet()->mask(); if (k==K_TAB && f.focusdirty()) { // propone il prezzo in base alla causale if (!f.mask().get(F_QUANT).blank() && !f.mask().get(F_CODART).blank()) { real prz=m.proposed_price(f.mask().get(F_CODART), f.mask().get_real(F_QUANT), f.mask().get(F_CAUSRIG)); f.mask().set(F_PREZZO,prz); } } return TRUE; } bool TMask_movmag::update_rigamov (int r, const char * old_codcaus, const char * old_codart, const real & old_quant) { bool added_some=add_autorows(r, old_codcaus, old_codart, old_quant); if (added_some) add_explrows(r+1); added_some |=add_explrows(r); return added_some; } bool TMask_movmag::add_autorows (int r, const char * old_codcaus, const char * old_codart, const real & old_quant) { bool added_some=FALSE; TSheet_field & ss=(TSheet_field & )field(F_RIGHE); real new_factor(ss.cell(r,ss.cid2index(F_QUANT))); new_factor = old_quant.is_zero() ? ZERO : new_factor / old_quant; TString16 new_codcaus(ss.cell(r,ss.cid2index(F_CAUSRIG))); if (new_codcaus.blank()) new_codcaus=get(F_CODCAUS); TCausale_magazzino &oldcau=(TCausale_magazzino &)cache_causali.get(old_codcaus); TCausale_magazzino &cau =(TCausale_magazzino &)cache_causali.get(new_codcaus); bool rimuovi_righe_coll=FALSE; bool inserisci_righe_coll=*cau.caus_collegata()!='\0'; if (inserisci_righe_coll) { // ******************************* // deve esserci una riga collegata TCausale_magazzino &cau_coll =(TCausale_magazzino &)cache_causali.get(cau.caus_collegata()); if ((r < ss.items()-1 && *ss.cell(r+1,ss.cid2index( F_AUTOMATICA)) == riga_automatica) && cau_coll.esplodente() && strcmp(old_codart,ss.cell(r,ss.cid2index( F_CODART)))!=0 ) { // ho cambiato il codice articolo del finito: rimuovo le righe automatiche esplose rimuovi_righe_coll=TRUE; } } else if (*oldcau.caus_collegata()!='\0') // ho cambiato causale, passando ad una che non ha collegamenti rimuovi_righe_coll=TRUE; // ****************** if (rimuovi_righe_coll) { while (r < ss.items()-1 && *ss.cell(r+1,ss.cid2index( F_AUTOMATICA)) == riga_automatica) ss.destroy(r + 1); } // ****************** if (inserisci_righe_coll) { TCausale_magazzino &cau_coll =(TCausale_magazzino &)cache_causali.get(cau.caus_collegata()); TString tmpstr; int offset=1; #define COPIA_SU_AUTO(colnum) {tmpstr=(ss.row(r).get(ss.cid2index(colnum))); ss.row(r+offset).add(tmpstr,ss.cid2index(colnum));} if ((r == ss.items()-1 || r < ss.items()-1 && *ss.cell(r+1,ss.cid2index( F_AUTOMATICA)) != riga_automatica)) { // manca, la inserisco ss.insert(r+offset); ss.row(r+offset)=ss.row(r); ss.row(r+offset).add(TString(1,riga_automatica),ss.cid2index(F_AUTOMATICA)); if (cau_coll.has_default_mag()) ss.row(r+1).add(cau_coll.default_mag(),ss.cid2index(F_CODMAG)); if (cau_coll.has_default_dep()) ss.row(r+1).add(cau_coll.default_mag(),ss.cid2index(F_CODDEP)); COPIA_SU_AUTO(F_PREZZO); added_some= TRUE; } while (r+offset < ss.items() && *ss.cell(r+offset,ss.cid2index( F_AUTOMATICA))==riga_automatica) { // riporta eventuali cambiamenti della riga "Master" sulle righe automatice if (*ss.cell(r+offset,ss.cid2index( F_ESPLOSA)) <=' ') { COPIA_SU_AUTO(F_CODART); COPIA_SU_AUTO(F_LIV1); COPIA_SU_AUTO(F_LIV2); COPIA_SU_AUTO(F_LIV3); COPIA_SU_AUTO(F_LIV4); COPIA_SU_AUTO(F_UM); COPIA_SU_AUTO(F_QUANT); ss.row(r+offset).add(cau.caus_collegata(),ss.cid2index(F_CAUSRIG)); ss.check_row(r+offset); ss.force_update(r+offset); } else { if (new_factor != 1.0) { real q(ss.row(r+offset).get(ss.cid2index(F_QUANT))); q*=new_factor; tmpstr=q.string(); ss.row(r+offset).add(tmpstr,ss.cid2index(F_QUANT)); ss.force_update(r+offset); } } offset++; } } return added_some; } bool TMask_movmag::add_explrows(int r) { TSheet_field & sheet=(TSheet_field & )field(F_RIGHE); TString16 new_codcaus(sheet.cell(r,sheet.cid2index(F_CAUSRIG))); if (new_codcaus.blank()) new_codcaus=get(F_CODCAUS); bool added_some=FALSE; TCausale_magazzino &cau =(TCausale_magazzino &)cache_causali.get(new_codcaus); if (cau.esplodente() && *sheet.cell(r,sheet.cid2index(F_ESPLOSA)) == ' ') { TDistinta_tree distinta; TArray boom; // ******************************* // c'e' una riga di movimento esplodente non ancora esplosa: // va sostituita con n righe esplose TString codmag; real prezzo,quant; distinta.set_root(sheet.cell(r,sheet.cid2index(F_CODART))); distinta.explode(boom); for (int newrow=0; newrow < boom.items() ; newrow++) { TRiga_esplosione & riga_esp=(TRiga_esplosione & )(boom[newrow]); sheet.insert(r+newrow+1); TToken_string & nuova_riga=sheet.row(r+newrow+1); nuova_riga=sheet.row(r); nuova_riga.add(riga_esp.articolo() ,sheet.cid2index(F_CODART)); nuova_riga.add(riga_esp.um() , sheet.cid2index(F_UM)); quant=sheet.row(r).get(sheet.cid2index(F_QUANT)); quant*=riga_esp.val(); nuova_riga.add(quant.string() , sheet.cid2index(F_QUANT)); if (codmag.not_empty()) { nuova_riga.add(codmag.sub(1,3) ,sheet.cid2index(F_CODMAG)); nuova_riga.add(codmag.sub(4,5) ,sheet.cid2index(F_CODDEP)); } if (!prezzo.is_zero()) nuova_riga.add(prezzo.string(),sheet.cid2index(F_PREZZO)); nuova_riga.add("X",sheet.cid2index(F_ESPLOSA)); sheet.check_row(r+1+newrow); sheet.force_update(r+1+newrow); added_some=TRUE; } // elimino la riga "padre" sheet.destroy(r); } return added_some; } real TMask_movmag::proposed_price(const char *codart, real quant, const char *causrig) { real rv("0"); TCausale_magazzino & cau= (TCausale_magazzino &)cache_causali.get(*causrig ? causrig : get(F_CODCAUS)); TLocalisamfile anamag(LF_ANAMAG); anamag.put("CODART",codart); anamag.read(); switch (cau.tipoprz()) { // prezzo case 'P': { TLocalisamfile umart(LF_UMART); TConfig cfgditta(CONFIG_DITTA); TCondizione_vendita cv(&cfgditta,&anamag,&umart); cv.put_listino(get(F_CODLIST),get(F_CATVEN)); cv.ricerca(codart,quant); rv=cv.get_prezzo(); } break; // costo case 'C': { rv=anamag.get_real("ULTCOS1"); } break; } return rv; } bool TMask_movmag::handle_codcaus(TMask_field &fld, KEY k) { static TString16 old_codcaus; if (k == K_TAB && fld.focusdirty() && old_codcaus!="") { // aggiorna le righe di sheet TMask_movmag &m=(TMask_movmag &)fld.mask(); TSheet_field & ss=(TSheet_field & )m.field(F_RIGHE); bool added_some; // aggiorna le righe che dipendono dalla causale movimento for (int i=0; i< ss.items(); i++) { if (*ss.cell(i,ss.cid2index(F_CAUSRIG)) ==' ') added_some &=(m.update_rigamov(i,old_codcaus,ss.cell(i,ss.cid2index(F_CODART)), real(ss.cell(i,ss.cid2index(F_QUANT))))); } if (added_some) { ss.dirty(); ss.set_focus(); } } if (k == K_TAB) old_codcaus=fld.get(); return TRUE; } bool TMask_movmag::handle_datacomp(TMask_field &fld, KEY k) { if (k == K_TAB) // && fld.focusdirty()) { int codes=((TMask_movmag &)fld.mask()).mov_mag->codice_esercizio(TDate(fld.get())); if (codes>0) { fld.mask().field(F_ANNOES).set(codes); fld.mask().field(H_ANNOES).set(codes); } else { fld.error_box("La data indicata non appartiene a nessuno degli esercizi contabili inseriti ") ; return FALSE; } } return TRUE; } class TApp_movmag: public TRelation_application { TArray used_files; TMask_movmag *_msk; // maschera principale TCodgiac_livelli * _livelli_giac;// oggetto handler per i livelli di giacenza TRelation * _rel; // relazione contenente il file movimenti virtual bool user_create(); virtual bool user_destroy(); virtual TMask *get_mask(int) { return _msk; } virtual bool changing_mask(int) { return FALSE; } virtual TRelation *get_relation() const { return _rel; } virtual const char *get_next_key(); TString16 _nextcod; public: TApp_movmag() {}; virtual ~TApp_movmag() {}; }; inline TApp_movmag& app() { return (TApp_movmag&) main_app(); } bool TApp_movmag::user_create() { used_files.add(new TLocalisamfile(LF_ANAMAG)); used_files.add(new TLocalisamfile(LF_UMART)); used_files.add(new TLocalisamfile(LF_MOVMAG)); used_files.add(new TLocalisamfile(LF_RMOVMAG)); used_files.add(new TTable("%CAU")); TMov_mag * m_m= new TMov_mag(); // record del movimento di magazzino m_m->enable_autoload(LF_RMOVMAG); // gestione giacenza a livelli _livelli_giac= new TCodgiac_livelli; // maschera specifica con gli handler dei movimenti _msk= new TMask_movmag(_livelli_giac,m_m); // relazione con un solo file (LF_MOVMAG) ma col record Head_Body _rel= new TRelation(LF_MOVMAG); _rel->lfile().set_curr(m_m); return TRUE; } bool TApp_movmag::user_destroy() { delete _rel; delete _msk; delete _livelli_giac; return TRUE; } // autonumerazione const char *TApp_movmag::get_next_key() { const char* nk = ((TMov_mag &)_rel->curr()).get_next_key(); return _nextcod.format("%d|%s",F_NUMREG, nk); } int mg1100(int argc, char* argv[]) { TApp_movmag a; a.run(argc, argv, "Movimenti di magazzino"); exit(0); return 0; }