#include #include #include #include #include #include #include "velib01.h" #include "ve2400.h" class TAnagrafica_magazzino: public TRelation_application { TMask *_msk; // maschera principale TRelation *_rel; // relazione principale di un solo file (anagrafiche di magazzino) TLocalisamfile *_umart; // file di accesso alle unità di misura TLocalisamfile *_deslin; // file di accesso alle descrizioni in lingua TLocalisamfile *_codcorr; // file di accesso ai codici corrispondenti TRecord_array *_linee_rec0; // record array di accoppiamento delle unità di misura TRecord_array *_linee_rec1; // record array di accoppiamento delle descrizioni in lingua con il primo sheet TRecord_array *_linee_rec2; // record array di accoppiamento delle codici corrispondenti con il secondo sheet 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 void init_insert_mode(TMask &); virtual int read(TMask& m); virtual bool remove(); virtual int write(const TMask& m); virtual int rewrite(const TMask& m); static bool handle_sheet0(TMask_field &, KEY); // handler dello sheet delle unità di misura static bool notify_sheet0(TSheet_field & s, int r, KEY k); // handler dello sheet delle unità di misura static bool handle_sheet1(TMask_field &, KEY); // handler dello sheet delle descrizioni in lingua static bool handle_sheet2(TMask_field &, KEY); // handler dello sheer dei codici alternativi static bool handle_sheet0_um(TMask_field &, KEY); // handler del campo UM dello sheet delle unità di misura static bool handle_sheet0_price(TMask_field &, KEY); // handler del campo PREZZO e PREZZO_LORDO dello sheet delle unità di misura public: TAnagrafica_magazzino() {} virtual ~TAnagrafica_magazzino() {} }; inline TAnagrafica_magazzino& app() { return (TAnagrafica_magazzino&) main_app(); } bool TAnagrafica_magazzino::user_create() { _msk= new TMask("ve2400"); _msk->set_handler(F_SHEET0, handle_sheet0); ((TSheet_field &)_msk->field(F_SHEET0)).set_notify(notify_sheet0); _msk->set_handler(F_SHEET1, handle_sheet1); _msk->set_handler(F_SHEET2, handle_sheet2); TSheet_field &f= (TSheet_field &)_msk->field(F_SHEET0); TMask &fm= f.sheet_mask(); fm.set_handler(FS_CODUM, handle_sheet0_um); fm.set_handler(FS_PREZZO, handle_sheet0_price); fm.set_handler(FS_PREZZO_LORDO, handle_sheet0_price); _rel= new TRelation(LF_ANAMAG); _umart= new TLocalisamfile(LF_UMART); _deslin= new TLocalisamfile(LF_DESLIN); _codcorr= new TLocalisamfile(LF_CODCORR); _linee_rec0= new TRecord_array(LF_UMART, "NRIGA"); _linee_rec1= new TRecord_array(LF_DESLIN, "NRIGA"); _linee_rec2= new TRecord_array(LF_CODCORR, "NRIGA"); return TRUE; } bool TAnagrafica_magazzino::user_destroy() { delete _linee_rec2; delete _linee_rec1; delete _linee_rec0; delete _codcorr; delete _deslin; delete _umart; delete _rel; delete _msk; return TRUE; } int TAnagrafica_magazzino::read(TMask& m) { const int err= TRelation_application::read(m); if (err == NOERR) { TSheet_field &f0= (TSheet_field &)m.field(F_SHEET0); // prende il sheet delle unità di misura TRectype rum(_umart->curr()); // prende il record corrente dal file delle unità di misura TString codiva(m.get(F_CODIVA)); real netto = 0.0, lordo = 0.0; f0.destroy(); // cancella lo sheet rum.zero(); rum.put("CODART", m.get(F_CODART)); // imposta il record corrente sul codice articolo (dalla maschera) _linee_rec0->read(rum); // legge il record array const int lastum = _linee_rec0->last_row(); for (int i= 1; i <= lastum; i++) { TRectype &rec= _linee_rec0->row(i, TRUE); // prende il record della riga corrente dal record array TToken_string &row= f0.row(i-1); row = ""; row.add(rec.get("UM")); // imposta la riga dello sheet con i campi del record della riga corrente row.add(rec.get("FC")); row.add(rec.get("PREZZO")); netto = real(rec.get("PREZZO")); lordo = netto2lordo(netto,codiva); row.add(lordo.string()); } if (f0.items() == 0) ((TToken_string &)f0.row(0)) = "|1"; // aggiunge una riga allo sheet else ((TToken_string &)f0.row(0)).add("1",1); // forza la prima unita' di misura a 1 f0.disable_cell(0, 1); // mette in sola lettura il secondo campo della prima riga (il fattore di conversione della prima U.M. è fisso a 1) f0.force_update(0); // aggiorna lo stato della riga 0 TRectype r(_deslin->curr()); // prende il record corrente dal file delle descrizioni in lingua TSheet_field &f1= (TSheet_field &)m.field(F_SHEET1); // prende il sheet delle descrizioni in lingua r.zero(); r.put("CODART", m.get(F_CODART)); // imposta il record corrente sul codice articolo (dalla maschera) _linee_rec1->read(r); // legge il record array f1.destroy(); // cancella lo sheet const int lastdes= _linee_rec1->last_row(); for (i = 1; i <= lastdes; i++) { TRectype &rec= _linee_rec1->row(i, TRUE); // prende il record della riga corrente dal record array TToken_string &row= f1.row(i-1); row = ""; row.add(rec.get("CODLIN")); // imposta la riga dello sheet con i campi del record della riga corrente row.add(rec.get("DESCR")); } TRectype rcor(_codcorr->curr()); // prende il record corrente dal file dei codici corrispondenti TSheet_field &f2= (TSheet_field &)m.field(F_SHEET2); // prende lo sheet dei codici corrispondenti rcor.zero(); rcor.put("CODART", m.get(F_CODART)); // imposta il record corrente sul codice articolo (dalla maschera) _linee_rec2->read(rcor); // legge il record array f2.destroy(); // cancella lo sheet const int lastcod = _linee_rec2->last_row(); for (i= 1; i <= lastcod; i++) { TRectype &rec= _linee_rec2->row(i, TRUE); // prende il record della riga corrente dal record array TToken_string &row= f2.row(i-1); row = ""; row= rec.get("CODARTALT"); // imposta la riga dello sheet con i campi del record della riga corrente row.add(rec.get("TIPO")); } } return err; } bool TAnagrafica_magazzino::remove() { return _linee_rec0->remove() == NOERR && _linee_rec1->remove() == NOERR && _linee_rec2->remove() == NOERR && TRelation_application::remove(); } int TAnagrafica_magazzino::write(const TMask& m) { int err= TRelation_application::write(m); if (err != NOERR) return err; TSheet_field &f0= (TSheet_field &)m.field(F_SHEET0); _linee_rec0->destroy_rows(); if (m.insert_mode()) _linee_rec0->renum_key("CODART", m.get(F_CODART)); for (int i= 0; i < f0.items(); i++) { TToken_string &row= f0.row(i); TString16 um(row.get(0)); um.rtrim(); if (um.not_empty()) { TRectype &rec= _linee_rec0->row(i+1, TRUE); rec.put("UM", um); rec.put("FC", row.get()); rec.put("PREZZO", row.get()); } } err = _linee_rec0->write(); if (err != NOERR) return err; TSheet_field &f1= (TSheet_field &)m.field(F_SHEET1); _linee_rec1->destroy_rows(); if (m.insert_mode()) _linee_rec1->renum_key("CODART", m.get(F_CODART)); for (i = 0; i < f1.items(); i++) { TToken_string &row= f1.row(i); TString16 codlin(row.get(0)); codlin.rtrim(); if (codlin.not_empty()) { TRectype &rec= _linee_rec1->row(i+1, TRUE); rec.put("CODLIN", codlin); rec.put("DESCR", row.get()); } } err= _linee_rec1->write(); if (err != NOERR) return err; TSheet_field &f2= (TSheet_field &)m.field(F_SHEET2); _linee_rec2->destroy_rows(); if (m.insert_mode()) _linee_rec2->renum_key("CODART", m.get(F_CODART)); for (i= 0; i < f2.items(); i++) { TToken_string &row= f2.row(i); TString80 codartalt(row.get(0)); codartalt.rtrim(); if (codartalt.not_empty()) { TRectype &reccor= _linee_rec2->row(i+1, TRUE); reccor.put("CODARTALT", codartalt); reccor.put("TIPO", row.get()); } } err= _linee_rec2->write(); return err; } int TAnagrafica_magazzino::rewrite(const TMask& m) { TSheet_field &f0= (TSheet_field &)m.field(F_SHEET0); _linee_rec0->destroy_rows(); if (m.insert_mode()) _linee_rec0->renum_key("CODART", m.get(F_CODART)); for (int i= 0; i < f0.items(); i++) { TToken_string & row = f0.row(i); TString16 um(row.get(0)); um.rtrim(); if (um.not_empty()) { TRectype &rec= _linee_rec0->row(i+1, TRUE); rec.put("UM", um); rec.put("FC", row.get()); rec.put("PREZZO", row.get()); } } int err = _linee_rec0->rewrite(); if (err != NOERR) return err; TSheet_field &f1= (TSheet_field &)m.field(F_SHEET1); _linee_rec1->destroy_rows(); if (m.insert_mode()) _linee_rec1->renum_key("CODART", m.get(F_CODART)); for (i= 0; i < f1.items(); i++) { TToken_string & row = f1.row(i); TString16 codlin(row.get(0)); codlin.rtrim(); if (codlin.not_empty()) { TRectype &rec= _linee_rec1->row(i+1, TRUE); rec.put("CODLIN", codlin); rec.put("DESCR", row.get()); } } err = _linee_rec1->rewrite(); if (err != NOERR) return err; TSheet_field &f2= (TSheet_field &)m.field(F_SHEET2); _linee_rec2->destroy_rows(); if (m.insert_mode()) _linee_rec2->renum_key("CODART", m.get(F_CODART)); for (i = 0; i < f2.items(); i++) { TToken_string &row= f2.row(i); TString80 codartalt(row.get(0)); codartalt.rtrim(); if (codartalt.not_empty()) { TRectype &reccor = _linee_rec2->row(i+1, TRUE); reccor.put("CODARTALT", codartalt); reccor.put("TIPO", row.get()); } } err = _linee_rec2->rewrite(); if (err == NOERR) err= TRelation_application::rewrite(m); return err; } void TAnagrafica_magazzino::init_insert_mode(TMask &m) { TSheet_field &f= (TSheet_field &)m.field(F_SHEET0); if (f.items()==0) { ((TToken_string &)f.row(0)) = "|1"; // aggiunge una riga allo sheet f.disable_cell(0, 1); // mette in sola lettura il secondo campo della prima riga (il fattore di conversione della prima U.M. è fisso a 1) f.force_update(0); // aggiorna lo stato della riga 0 } } bool TAnagrafica_magazzino::handle_sheet0(TMask_field &fld, KEY k) { if (k == K_ENTER) { TSheet_field &f= (TSheet_field &)fld; // typecast del campo al suo sheet corrispondente const int items = f.items(); if (items > 0) { TAssoc_array v; // istanzia l'hash table per il controllo di univocità for (int i= 0; i 0); return TRUE; } bool TAnagrafica_magazzino::handle_sheet1(TMask_field &fld, KEY k) { if (k == K_ENTER) { TSheet_field &f= (TSheet_field &)fld; // typecast del campo al suo sheet corrispondente const int items = f.items(); if (items > 0) { TAssoc_array v; // istanzia l'hash table per il controllo di univocità for (int i= 0; i < items; i++) { const TString16 codlin(f.cell(i,0)); if (codlin.empty()) return error_box("I codici lingua non possono essere vuoti"); if (v.add(codlin)) return error_box("I codici lingua devono essere diversi tra loro"); // aggiunge all'hash table l'elemento 0 (primo) della riga corrente e controlla che non esista già } } } return TRUE; } bool TAnagrafica_magazzino::handle_sheet2(TMask_field &fld, KEY k) { if (k==K_ENTER) { TSheet_field &f= (TSheet_field &)fld; // typecast del campo al suo sheet corrispondente const int items = f.items(); if (items > 0) { TMask &m= fld.mask(); // prende la maschere d'origine del campo TAssoc_array v; // istanzia l'hash table per il controllo di univocità v.add(m.get(F_CODART)); // aggiunge all'hash table il codice articolo originale for (int i= 0; i< items; i++) { const TString80 codart(f.cell(i,0)); if (codart.empty()) return error_box("I codici alternativi non possono essere vuoti"); if (v.add(codart)) return error_box("I codici alternativi devono essere diversi tra loro e dal codice dell'articolo"); // aggiunge all'hash table l'elemento 0 (primo) della riga corrente e controlla che non esista già } } } return TRUE; } bool TAnagrafica_magazzino::handle_sheet0_um(TMask_field &fld, KEY k) { if (fld.focusdirty() && k == K_TAB) { TMask &m = fld.mask(); // prende la maschera d'origine del campo (maschera dello sheet) const TString16 curr_um(fld.get()); // prende il contenuto del campo corrente (unità di misura corrente) if (curr_um.not_empty()) // se il codice dell'unità di misura è vuoto non viene fatto alcun calcolo { TSheet_field *f= m.get_sheet(); // prende lo sheet d'origine della maschera del campo CHECK(f != NULL, "Il puntatore allo sheet è nullo"); if (f->selected() > 0) { // ALGORITMO DI PRECALCOLO DEL RAPPORTO DELLE UNITA' DI MISURA NELLO SHEET // // SHEET: // ----- // riga u.m. f.c. // 1) KM 1 -> kilometri (you), riferiti al metro (your) con f.c. 1000 (your_fc) // ... ... ... // ...) MM X -> millimetri (me), riferiti al metro (my) con f.c. 0,001 (my_fc) // // se (your==my) allora X=(my_fc/your_fc) ...chiaro, no!? :-) TTable t("%UMS"); real x; // fattore di conversione dell'unità di misura corrente const TString16 first_um(f->row(0).get(0)); // prende l'unità di misura di rapporto (dalla prima linea dello sheet) t.zero(); t.put("CODTAB", curr_um); if (t.read() == NOERR) { const TString16 rif_um(t.get("S7")); // prende l'unità di misura di riferimento dell'unità di misura corrente x = t.get_real("R10"); // prende il suo fattore di conversione if (rif_um != first_um) { t.zero(); t.put("CODTAB", first_um); if (t.read() == NOERR) { TString16 first_um_rif(t.get("S7")); // prende l'unità di misura di riferimento dell'unità di misura di rapporto const real first_um_rif_fc(t.get_real("R10")); // prende il suo fattore di conversione if (first_um_rif == rif_um) { x /= first_um_rif_fc; // calcola il rapporto tra i fattori di conversione x.round(5); // arrotonda il risultato a 5 decimali } } } } if (x == ZERO) x = 1.00; m.set(FS_FCUM, x); // il risultato viene scritto nel campo del fattore di conversione } } } return TRUE; } bool TAnagrafica_magazzino::handle_sheet0_price(TMask_field &f, KEY k) { if (f.to_check(k,TRUE)) { TMask& m = f.mask(); TString codiva = app()._msk->get(F_CODIVA); real netto = 0.0; real lordo = 0.0; if (f.dlg() == FS_PREZZO) { netto = real(m.get(FS_PREZZO)); lordo = netto2lordo(netto,codiva); m.set(FS_PREZZO_LORDO,lordo.string()); } else { lordo = real(m.get(FS_PREZZO_LORDO)); real prec_lordo = lordo; netto = lordo2netto(lordo,codiva); if (lordo != prec_lordo) { warning_box("Scorporando l'iva dal prezzo lordo si e' dovuto\n" "correggere quest'ultimo a causa di arrotondamenti."); m.set(FS_PREZZO_LORDO,lordo.string()); } m.set(FS_PREZZO,netto.string()); } } return TRUE; } int ve2400(int argc, char* argv[]) { TAnagrafica_magazzino a; a.run(argc, argv, "Anagrafica di magazzino "); return 0; }