#include #include #include "../ve/sconti.h" #include "../ve/ve0100.h" #include "../ve/veini.h" #include "../ve/veuml.h" #include "../ve/veuml3.h" #include "../ve/verig.h" #include "../ve/vepriv.h" #include "../ve/velib.h" #include "../ve/velib04.h" #define F_K F_USERFLD #define F_LIVELLO F_USERFLD+1 #define F_DETTAGLIO F_USERFLD+2 #define F_COPIA F_USERFLD+3 #define F_INCOLLA F_USERFLD+4 #define F_SHRINK_ALL F_USERFLD+5 #define F_ZOOM_ALL F_USERFLD+6 #define F_SHRINK_ROW F_USERFLD+7 #define F_ZOOM_ROW F_USERFLD+8 #define F_USEK F_USERFLD+9 #define F_REVISION F_USERFLD+10 #define F_LOAD_COSTS F_USERFLD+11 #define F_COPIA_TUTTO F_USERFLD+12 #define F_TIPO_COSTO F_USERFLD+13 #define FOR_EACH_DOC_ROW_BACK(d, r, row) const TRiga_documento* row = NULL; for (int r = d.rows(); r > 0 && (row = &d[r]) != NULL; r--) ////////////////////////////////////////// //// CLASSE TGestione_preventivo_msk //// ////////////////////////////////////////// //Definizione della classe della maschera class TGestione_preventivo_msk : public TDocumento_mask { int _rule; int _clipboard_row; long _clipboard_ndoc; char _clipboard_provv; TString8 _clipboard_codnum; int _clipboard_anno; TString16 _field_costo; protected: //hanlder di documento: static bool pe_data_handler(TMask_field& f, KEY k); //handler di riga: static bool pe_ritirato_handler(TMask_field& f, KEY k); static bool pe_codart_handler(TMask_field& f, KEY k); static bool pe_qta_handler(TMask_field& f, KEY k); static bool pe_k_handler(TMask_field& f, KEY k); static bool pe_prezzo_handler(TMask_field& f, KEY k); static bool pe_costo_handler(TMask_field& f, KEY k); static bool ss_notify(TSheet_field& ss, int r, KEY key); virtual void on_idle(); virtual void highlight_row(int row, COLOR back = COLOR_INVALID, COLOR fore = COLOR_INVALID, bool dirty = true, bool update = true); const TString & build_tree_string(int level); bool new_revision(const char* codnum, long& ndoc) const; public: static bool pe_espandi_handler(TMask_field& f, KEY k); static bool pe_espandi_riga_handler(TMask_field& f, KEY k); static bool pe_copia_handler(TMask_field& f, KEY k); static bool pe_incolla_handler(TMask_field& f, KEY k); static bool pe_new_revision_handler(TMask_field& f, KEY k); static bool pe_update_costi_handler(TMask_field& f, KEY k); virtual void user_set_handler( short fieldid, int index); virtual void user_set_row_handler(TMask& rm, short field, int index); const real get_costo(const TArticolo_giacenza & art); void update_prezzo_vendita(TMask & row_mask); void update_costi_ricavi(int row = -1, bool update_sheet = false); bool var_cost() const { return _field_costo == "VAR"; } virtual TVariable_mask * riga_mask(int numriga); virtual void doc2mask(bool reload_clifo = true, bool force_load = false, bool update = true); TGestione_preventivo_msk(const char* tipodoc); }; ////////////////////////////////////////// //// CLASSE TGestione_preventivo_APP //// ////////////////////////////////////////// // Definizione della classe dell'applicazione motore class TGestione_preventivo_app : public TMotore_application { protected: virtual TMask* get_mask( int mode ); virtual int write( const TMask& m ); virtual int rewrite( const TMask& m ); virtual int read ( TMask& m ); virtual void init_insert_mode( TMask& m ); virtual void init_modify_mode(TMask &m); void elimina_vuote( const TMask& m); virtual bool last_doc(char provv, int anno, const char* codnum, long& ndoc, TDate& datadoc) const; public: TGestione_preventivo_app() {} }; inline TGestione_preventivo_app& peapp() { return (TGestione_preventivo_app &)main_app(); }; ////////////////////////////////////////// //// CLASSE TGestione_preventivo_MSK //// ////////////////////////////////////////// const TString & TGestione_preventivo_msk::build_tree_string(int level) { TString & tree = get_tmp_string(30); if (level < 10) { tree.fill(' ', level + 3); tree << '+'; tree.rpad(13, '-'); } else tree = " +"; TString l; l.format("%02d", level + 1); tree.overwrite(l, 0, 2); return tree; } //////////////////////////// // HANDLER DI DOCUMENTO // //////////////////////////// void TGestione_preventivo_msk:: on_idle() { TDocumento_mask::on_idle(); } //magico metodo per settare, al cambio riga dello sheet, il focus sul campo desiderato (il campo in questione è.. //..definito nella on_idle(); ricordarsi la set_notify() nel costruttore della maschera senno' viene eseguito l'ss_notify().. //..standard e non questo qui ridefinito. Allah! void TGestione_preventivo_msk::update_costi_ricavi(int nrow, bool update_sheet) { TDocumento& d = doc(); const int rows = d.physical_rows(); TArray valori; TArray costi; TSheet_field & sh = sfield(F_SHEET); const bool all = nrow < 0; if (all) nrow = rows; else d[nrow].autosave(sh); const int cur_level = d[nrow].get_int(RDOC_LEVEL); while (nrow < rows && cur_level < d[nrow + 1].get_int(RDOC_LEVEL)) nrow++; for (int i = nrow; i > 0; i--) { TRiga_documento& row = d[i]; const int level = row.get_int(RDOC_LEVEL); if (i == rows || level >= doc()[i + 1].get_int(RDOC_LEVEL)) { const real importo = row.importo(true, false); row.put(RDOC_VALV, importo); for (int j = level - 1; j >= 0; j--) { real * r = (real *) valori.objptr(j); if (r == NULL) { r = new real; valori.add(r, j); } *r += importo; } const real costo = row.get_real(RDOC_QTA) * row.get_real(RDOC_COSTO); row.put(RDOC_VALC, costo); for (int j = level - 1; j >= 0; j--) { real * r = (real *) costi.objptr(j); if (r == NULL) { r = new real; costi.add(r, j); } *r += costo; } } else { real * r = (real *) valori.objptr(level); if (r != NULL) { row.put(RDOC_VALV, *r); *r = ZERO; } r = (real *) costi.objptr(level); if (r != NULL) { row.put(RDOC_VALC, *r); *r = ZERO; } } if (update_sheet) { row.autoload(sh); sh.check_row(i - 1); sh.force_update(i - 1); } if (!all && level <= 0) break; } } bool TGestione_preventivo_msk::ss_notify(TSheet_field& ss, int r, KEY key) { TGestione_preventivo_msk& mask = (TGestione_preventivo_msk&) ss.mask(); TSheet_field & sh = mask.sfield(F_SHEET); TDocumento& doc = mask.doc(); switch (key) { case K_TAB: // entrata { TRiga_documento& row = doc[r + 1]; TMask & row_mask = sh.sheet_row_mask(r); const int level = row.get_int(RDOC_LEVEL); const bool prodfin = level == 0; const bool price_enabled = (r + 1 == doc.physical_rows()) || (level >= doc[r + 2].get_int(RDOC_LEVEL)); short id; sh.enable_cell(r, sh.cid2index(FR_PREZZO), price_enabled); sh.enable_cell(r, sh.cid2index(FR_JOLLY3), price_enabled); for (id = FR_CDC1; id < FR_CDC12; id++) sh.enable_cell(r, sh.cid2index(id), prodfin); for (id = FR_DESCDC1; id < FR_DESCDC12; id++) sh.enable_cell(r, sh.cid2index(id), prodfin); sh.force_update(r); } break; case K_CTRL + K_INS: // Inserimento { const int doc_row = r + 1; int level = 0; TRiga_documento & row = doc[doc_row]; if (r > 0 && row.is_merce()) { const int father_sheet_row = r - 1; TRiga_documento& father_row = doc[father_sheet_row + 1]; const int rows = doc.physical_rows(); level = father_row.get_int(RDOC_LEVEL); const int next_level = mask.get_int(F_LIVELLO); if ( next_level > 0 && (doc_row == rows || level > doc[doc_row + 1].get_int(RDOC_LEVEL))) level = (doc_row == rows || next_level - 1 >= doc[doc_row + 1].get_int(RDOC_LEVEL)) ? next_level - 1 : doc[doc_row + 1].get_int(RDOC_LEVEL); else if (mask.get_bool(F_DETTAGLIO) || (doc_row < rows && level < doc[doc_row + 1].get_int(RDOC_LEVEL))) level++; if (level > 0) { row.put(RDOC_CODCOSTO, father_row.get(RDOC_CODCOSTO)); row.put(RDOC_CODCMS, father_row.get(RDOC_CODCMS)); row.put(RDOC_FASCMS, father_row.get(RDOC_FASCMS)); if (level > father_row.get_int(RDOC_LEVEL)) { sh.disable_cell(father_sheet_row, sh.cid2index(FR_PREZZO)); sh.disable_cell(father_sheet_row, sh.cid2index(FR_JOLLY3)); father_row.zero(RDOC_COSTO); father_row.zero(RDOC_PREZZO); father_row.zero(RDOC_PPROV); father_row.zero(RDOC_K); father_row.autoload(sh); sh.force_update(father_sheet_row); } short id; for (id = FR_CDC1; id < FR_CDC12; id++) sh.disable_cell(r, sh.cid2index(id)); } } row.put(RDOC_LEVEL, level); row.put(RDOC_TREE, mask.build_tree_string(level)); row.autoload(sh); mask.reset(F_LIVELLO); mask.reset(F_DETTAGLIO); } break; case K_DEL: // Cancellazione { const int doc_row = r + 1; const int rows = doc.physical_rows(); if (doc_row < rows) { TRiga_documento & row = doc[doc_row]; const int level = row.get_int(RDOC_LEVEL); int i; int last_row = doc_row; for (i = doc_row + 1; i <= rows; i++) if (level < doc[i].get_int(RDOC_LEVEL)) last_row = i; else break; for (i = last_row; i > doc_row; i--) { doc.destroy_row(i, true); sh.destroy(i - 1); } sh.force_update(); } } break; case K_CTRL + K_DEL: // Cancellazione mask.update_costi_ricavi(-1, true); break; case K_ENTER: // Uscita con modifiche mask.update_costi_ricavi(r + 1, true); default: break; } return TDocumento_mask::ss_notify(ss, r, key); } void TGestione_preventivo_msk::highlight_row(int row, COLOR back, COLOR fore, bool dirty, bool update) { TDocumento_mask::highlight_row(row, back, fore, dirty, false); TRiga_documento& rigadoc = doc()[row + 1]; TSheet_field& sf = sfield(F_SHEET); COLOR back1 = back, back2 = COLOR_BLUE; const TColor_rule * c = (TColor_rule *) color_rules().objptr(_rule); if (c != NULL) c->colors(back2, fore); back = blend_colors(back1, back2, 1.0 - (((double) rigadoc.get_int(RDOC_LEVEL)) / 10.0)); sf.set_back_and_fore_color(back, fore, row); if (update) sf.force_update(row); } TVariable_mask * TGestione_preventivo_msk::riga_mask(int numriga) { const bool is_new = new_mask(numriga); TVariable_mask* m = TDocumento_mask::riga_mask(numriga); if (is_new && m != NULL) { const TRiga_documento& riga = doc()[numriga + 1]; TEdit_field & tree = m->add_string(FR_JOLLY1, 0, "Albero ", 2, 20, 13, "D_"); TEdit_field & k = m->add_string(FR_JOLLY2, 0, "K ", 25, 20, 25); TEdit_field & v = m->add_currency(FR_JOLLY3, 0, "Costo", 53, 20, 15, "U"); TEdit_field & p = m->add_string(FR_JOLLY4, 0, "", 75, 20, 1, "U"); m->set_handler(FR_CODART, pe_codart_handler); m->set_handler(FR_QTA, pe_qta_handler); m->set_handler(FR_PREZZO, pe_prezzo_handler); m->set_handler(FR_JOLLY2, pe_k_handler); m->set_handler(FR_JOLLY3, pe_costo_handler); tree.set_field(RDOC_TREE); k.set_field(RDOC_K); v.set_field(RDOC_COSTO); p.set_field(RDOC_PPROV); } return m; } void TGestione_preventivo_msk::doc2mask(bool reload_clifo, bool force_load, bool update) { TDocumento_mask::doc2mask(reload_clifo, force_load, false); TSheet_field& s = sfield(F_SHEET); const int righe = s.items(); const TDocumento & d = doc(); const bool has_k = get_bool(F_USEK); for (int i = 0; i < righe; i++) { const TRiga_documento & row = d[i + 1]; const int level = row.get_int(RDOC_LEVEL); const bool prodfin = level == 0; const bool price_enabled = (i + 1 == d.physical_rows()) || (level >= d[i + 2].get_int(RDOC_LEVEL)); s.enable_cell(i, s.cid2index(FR_PREZZO), price_enabled); s.enable_cell(i, s.cid2index(FR_JOLLY3), price_enabled); for (short id = FR_CDC1; id < FR_CDC12; id++) s.enable_cell(i, s.cid2index(id), prodfin); } //aggiorna i colori delle righe e forza l'update dello sheet highlight(); } //PE_TESTATA_HANDLER: handler che si occupa di decodificare i campi data in testata bool TGestione_preventivo_msk::pe_data_handler(TMask_field& f, KEY k) { bool ok = true; TGestione_preventivo_msk& mask = (TGestione_preventivo_msk&)f.mask(); return ok; } bool TGestione_preventivo_msk::pe_espandi_handler(TMask_field& f, KEY k) { if (k == K_SPACE) { TGestione_preventivo_msk& mask = (TGestione_preventivo_msk&)f.mask(); TSheet_field& sh = mask.sfield(F_SHEET); const int r = sh.selected(); const bool shrink = f.dlg() == F_SHRINK_ALL; const int size = shrink ? 1 : -1; int row_to_select = 0; FOR_EACH_SHEET_ROW(sh, i, row) { const int row_level = mask.doc()[i + 1].get_int(RDOC_LEVEL); if (row_level > 0) sh.set_row_height(i, size); else if (i <= r) row_to_select = i; } if (size < 0) sh.select(row_to_select); sh.force_update(); } return true; } bool TGestione_preventivo_msk::pe_espandi_riga_handler(TMask_field& f, KEY k) { if (k == K_SPACE) { TGestione_preventivo_msk& mask = (TGestione_preventivo_msk&)f.mask(); TSheet_field& sh = mask.sfield(F_SHEET); const int r = sh.selected(); const int level = mask.doc()[r + 1].get_int(RDOC_LEVEL); if (r >= 0 && r < sh.items()) { const bool shrink = f.dlg() == F_SHRINK_ROW; const int size = shrink ? 1 : -1; for (int i = r + 1; i < sh.items(); i++) { const int child_level = mask.doc()[i + 1].get_int(RDOC_LEVEL); if (child_level == level + 1) sh.set_row_height(i, size); else if (child_level > level + 1) sh.set_row_height(i, 1); else break; } } sh.force_update(); } return true; } bool TGestione_preventivo_msk::pe_copia_handler(TMask_field& f, KEY k) { bool ok = true; if (k == K_SPACE) { TGestione_preventivo_msk& mask = (TGestione_preventivo_msk&)f.mask(); mask._clipboard_ndoc = mask.get_long(F_NDOC); mask._clipboard_provv = mask.get(F_PROVV)[0]; mask._clipboard_codnum = mask.get(F_CODNUM); mask._clipboard_anno = mask.get_int(F_ANNO); mask._clipboard_row = f.dlg() == F_COPIA ? mask.sfield(F_SHEET).selected() + 1 : 0; } return ok; } bool TGestione_preventivo_msk::pe_incolla_handler(TMask_field& f, KEY k) { bool ok = true; if (k == K_SPACE) { TGestione_preventivo_msk& mask = (TGestione_preventivo_msk&)f.mask(); const bool alldoc = mask._clipboard_row == 0; const int cliprow = alldoc ? 1 : mask._clipboard_row; if (cliprow > 0) { TDocumento & dest = mask.doc(); TDocumento * newdoc = &mask.doc(); bool different_doc = dest.get_char(DOC_PROVV) != mask._clipboard_provv || dest.get_int(DOC_ANNO) != mask._clipboard_anno || dest.get(DOC_CODNUM) != mask._clipboard_codnum || dest.get_long(DOC_NDOC) != mask._clipboard_ndoc; if (different_doc) newdoc = new TDocumento(mask._clipboard_provv, mask._clipboard_anno, mask._clipboard_codnum, mask._clipboard_ndoc); TDocumento & orig = *newdoc; TSheet_field & sh = mask.sfield(F_SHEET); const int selected_row = sh.selected() + 1; const int rows = dest.physical_rows(); const int next_level = mask.get_int(F_LIVELLO); const int orig_level = orig[cliprow].get_int(RDOC_LEVEL); const int level = next_level > 0 ? next_level - 1 : orig_level; const int level_offset = level - orig_level; int i; int start_row = rows > 0 ? -1 : 1; for (i = selected_row; start_row < 0 && i <= rows; i++) { const int row_level = dest[i].get_int(RDOC_LEVEL); if (level == row_level) start_row = i; } if (start_row > 0) { const bool shift_source_rows = (!different_doc) && start_row <= cliprow; const int nrows = orig.physical_rows(); for (i = cliprow; i <= nrows; i++) { int row_level = orig[i].get_int(RDOC_LEVEL); if (!alldoc && i > cliprow && orig_level >= row_level) break; const TRiga_documento & row = orig[i]; sh.insert(start_row - 1, false, true); TRiga_documento & new_row = dest[start_row]; dest.copy_data(new_row, row); row_level += level_offset; new_row.put(RDOC_LEVEL, row_level); new_row.put(RDOC_TREE, mask.build_tree_string(row_level)); new_row.autoload(sh); start_row++; if (shift_source_rows) i++; } mask.highlight(); sh.force_update(); } if (different_doc) delete newdoc; mask.reset(F_LIVELLO); } } return ok; } bool TGestione_preventivo_msk::pe_new_revision_handler(TMask_field& f, KEY k) { bool ok = true; if (k == K_SPACE) { TGestione_preventivo_msk& mask = (TGestione_preventivo_msk&)f.mask(); TDocumento& d = mask.doc(); if (d.bloccato()) return f.error_box(TR("Documento bloccato: non e' possibile farne una nuova revisione")); TDocumento backup(d); const TTipo_documento& td = d.tipo(); const char stato_iniziale = d.stato(); d.put(DOC_STATO, td.stato_bloccato()); if (d.rewrite() == NOERR) { long ndoc = d.get_long(DOC_NDOC); if (mask.new_revision(d.get(DOC_CODNUM), ndoc)) { d.renum_ndoc(ndoc); d.put(DOC_STATO, td.stato_finale_inserimento()); ok = d.write() == NOERR; if (ok) { mask.enable(DLG_NEXTREC); // Mi assicuro che sia acceso il bottone Avanti mask.stop_run(K_NEXT); // Passo al documento successivo appena creato } } else ok = false; } else ok = false; if (!ok) { backup.stato(stato_iniziale); ok = backup.rewrite() == NOERR; } } return ok; } const real TGestione_preventivo_msk::get_costo(const TArticolo_giacenza & art) { if (_field_costo == "VAR") { const int annoes = esercizi().date2esc(doc().get_date(DOC_DATADOC)); switch (get_int(F_TIPO_COSTO)) { case 1 : // Ultimo costo return art.ultimo_costo(annoes); case 2 : // Media ultimi costi return art.media_costi(annoes); case 4 : // Costo standard return art.costo_standard(annoes); case 5 : // Costo medio return art.costo_medio(annoes, "", ""); case 6 : // Costo medio pond. return art.costo_mediopond(annoes, "", ""); default : return ZERO; } } return art.get_real(_field_costo); } bool TGestione_preventivo_msk::pe_update_costi_handler(TMask_field& f, KEY k) { if (k == K_SPACE) { TGestione_preventivo_msk & mask = (TGestione_preventivo_msk &) f.mask(); TDocumento & doc = mask.doc(); TSheet_field & sf = mask.sfield(F_SHEET); mask.mask2doc(); const int rows = doc.physical_rows(); for (int i = 1; i <= rows; i++) { bool ok = i == rows; TRiga_documento & row = doc[i]; const int level = row.get_int(RDOC_LEVEL); if (!ok) ok = (level >= doc[i + 1].get_int(RDOC_LEVEL)); if (ok) { const TString& codart = row.get(RDOC_CODARTMAG); if (codart.full()) { const TArticolo_giacenza & art = cached_article(codart); const real costo = mask.get_costo(art); row.put(RDOC_COSTO, costo); row.autoload(sf); } } } sf.force_update(); } return true; } /////////////////////// // HANDLER DI RIGA // /////////////////////// bool TGestione_preventivo_msk::pe_codart_handler(TMask_field& f, KEY k) { TMask& row_mask = f.mask(); bool ok = codart_handler( f, k ); TSheet_field * sh = row_mask.get_sheet(); if (ok && sh != NULL && k == K_TAB && f.focusdirty()) { TGestione_preventivo_msk & mask = (TGestione_preventivo_msk &) sh->mask(); const bool has_k = mask.get_bool(F_USEK); bool update = false; const int r = sh->selected(); const TString& codart = row_mask.get(FR_CODARTMAG); if (codart.full()) { const TArticolo_giacenza & art = cached_article(codart); const real costo = mask.get_costo(art); if (has_k) { const real ric = art.get(ANAMAG_PERCRIC); TString80 k; if (ric != ZERO) k = ric.string(); if (k.blank()) { const TString catmer = art.get(ANAMAG_GRMERC); k = cache().get("GMC", catmer, "S5"); if (k.blank()) k = cache().get("GMC", catmer.left(3), "S5"); } if (k.full()) row_mask.set(FR_JOLLY2, k); } row_mask.set(FR_JOLLY3, costo); } if (has_k || !row_mask.field(FR_PREZZO).enabled()) row_mask.set(FR_PREZZO, ""); row_mask.set(FR_JOLLY4, mask.condv().get_prov()); if (row_mask.field(FR_JOLLY3).enabled()) { if (row_mask.get(FR_PREZZO).blank() && row_mask.get(FR_JOLLY3).full()) mask.update_prezzo_vendita(row_mask); } else row_mask.set(FR_JOLLY3, ""); } if (k == K_F8) { TSheet_field * sh = row_mask.get_sheet(); if (sh != NULL) { TGestione_preventivo_msk & mask = (TGestione_preventivo_msk &) sh->mask(); TDocumento & doc = mask.doc(); const int rows = doc.physical_rows(); const bool has_k = mask.get_bool(F_USEK); const int start_level = doc[sh->selected() + 1].get_int(RDOC_LEVEL); for (int i = sh->selected() + 2; i <= rows; i++) { TRiga_documento & row = doc[i]; const int level = row.get_int(RDOC_LEVEL); if (level <= start_level) break; const bool prodfin = level == 0; const bool price_enabled = (i == doc.physical_rows()) || (level >= doc[i + 1].get_int(RDOC_LEVEL)); short id; sh->enable_cell(i - 1, sh->cid2index(FR_PREZZO), price_enabled); // sh->enable_cell(i - 1, sh->cid2index(FR_JOLLY2), price_enabled && has_k); sh->enable_cell(i - 1, sh->cid2index(FR_JOLLY3), price_enabled); const TString& codart = row.get(RDOC_CODARTMAG); const TArticolo_giacenza & art = cached_article(codart); const bool has_k = mask.get_bool(F_USEK); if (has_k || ! price_enabled) row.zero(RDOC_PREZZO); if (price_enabled && has_k) { const real ric = art.get(ANAMAG_PERCRIC); TString80 k; if (ric != ZERO) k = ric.string(); if (k.blank()) { const TString catmer = art.get(ANAMAG_GRMERC); k = cache().get("GMC", catmer, "S5"); if (k.blank()) k = cache().get("GMC", catmer.left(3), "S5"); } if (k.full()) row.put(RDOC_K, k); } if (price_enabled) { const real costo = mask.get_costo(art); row.put(RDOC_COSTO, costo); } for (id = FR_CDC1; id < FR_CDC12; id++) sh->enable_cell(i - 1, id, prodfin); for (id = FR_DESCDC1; id < FR_DESCDC12; id++) sh->enable_cell(i - 1, id, prodfin); row.put(RDOC_TREE, mask.build_tree_string(level)); row.autoload(*sh); mask.highlight_row(i -1, COLOR_INVALID, COLOR_INVALID, true, false); } sh->force_update(); } } return ok; } bool TGestione_preventivo_msk::pe_qta_handler(TMask_field& f, KEY k) { bool ok = qta_handler( f, k ); if (ok) { TMask& row_mask = f.mask(); TSheet_field * sh = row_mask.get_sheet(); if (sh != NULL) { TDocumento_mask & mask = (TDocumento_mask &) sh->mask(); TDocumento & doc = mask.doc(); if (k == K_F8) { const int r = sh->selected(); if (r > 0) { TRiga_documento & row = doc[r + 1]; const int level = row.get_int(RDOC_LEVEL); if (level > 0) { int father_row = r; while (r > 1 && level == doc[father_row].get_int(RDOC_LEVEL)) father_row--; TRiga_documento & row = doc[father_row]; const real qta_prec = row.get_real(RDOC_QTA); real qta(f.get()); TToken_string & shrow = sh->row(r); qta *= qta_prec; shrow.add(qta.string(), sh->cid2index(FR_QTA)); sh->force_update(r); row.put(RDOC_QTA, qta); f.focusdirty(); } } } if (f.to_check(k, true)) { const int r = sh->selected(); TRiga_documento & row = doc[r + 1]; const real old_qta = row.get_real(RDOC_QTA); const real qta = row_mask.get_real(FR_QTA); const int level = row.get_int(RDOC_LEVEL); if (old_qta != qta) { const int rows = doc.physical_rows(); for (int i = r + 2; i <= rows && level < doc[i].get_int(RDOC_LEVEL); i++) { TToken_string & shrow = sh->row(i - 1); real row_qta(shrow.get(sh->cid2index(FR_QTA))); row_qta *= qta; if (!old_qta.is_zero()) row_qta /= old_qta; row_qta.round(5); shrow.add(row_qta.string(), sh->cid2index(FR_QTA)); doc[i].put(RDOC_QTA, row_qta); } row.put(RDOC_QTA, qta); sh->force_update(); } } } } return ok; } void TGestione_preventivo_msk::update_prezzo_vendita(TMask & row_mask) { real costo = row_mask.get(FR_JOLLY3); TString k(row_mask.get(FR_JOLLY2)); TString ge; real perc; TSheet_field * sh = row_mask.get_sheet(); const int r = sh->selected(); if (k.blank()) k = get(F_K); if (scontoexpr2perc(k, false, ge, perc)) costo *= (real(2.00) - perc); TCurrency_documento prezzo(costo, doc(), true); row_mask.set(FR_PREZZO, prezzo.get_num().string()); row_mask.set(FR_JOLLY4, "K"); } bool TGestione_preventivo_msk::pe_k_handler(TMask_field& f, KEY k) { TMask& row_mask = f.mask(); TSheet_field * sh = row_mask.get_sheet(); if (sh == NULL) return true; TGestione_preventivo_msk& mask = (TGestione_preventivo_msk&)sh->mask(); const bool last_level = row_mask.field(FR_JOLLY3).enabled(); if (last_level) { if ((k == K_TAB && f.focusdirty()) || k == K_F8) mask.update_prezzo_vendita(row_mask); } else if (k == K_F8) { const TString k(row_mask.get(FR_JOLLY2)); const int r = sh->selected(); TDocumento & doc = mask.doc(); const int start_level = doc[r + 1].get_int(RDOC_LEVEL); TString ge; real perc; // row_mask.reset(FR_JOLLY2); sh->row(r).add("", sh->cid2index(FR_JOLLY2)); sh->force_update(r); for (int i = r + 2; i <= doc.physical_rows(); i++) { TRiga_documento & row = doc[i]; const int level = row.get_int(RDOC_LEVEL); if (level <= start_level) break; if (sh->cell_enabled(i -1, sh->cid2index(FR_PREZZO))) { TToken_string & shrow = sh->row(i - 1); row.put(RDOC_K, k); shrow.add(k, sh->cid2index(FR_JOLLY2)); TString row_k(k); if (row_k.blank()) row_k = mask.get(F_K); real val = row.get_real(RDOC_COSTO); if (scontoexpr2perc(row_k, false, ge, perc)) val *= (2 - perc); TCurrency_documento prezzo(val, doc, true); row.put(RDOC_PREZZO, prezzo.get_num()); row.put(RDOC_PPROV, "K"); shrow.add(prezzo.get_num().string(), sh->cid2index(FR_PREZZO)); shrow.add("K", sh->cid2index(FR_JOLLY4)); } } mask.update_costi_ricavi(r + 1, true); } return true; } bool TGestione_preventivo_msk::pe_prezzo_handler(TMask_field& f, KEY k) { TMask& row_mask = f.mask(); const bool last_level = row_mask.field(FR_JOLLY3).enabled(); if (last_level) { if (k == K_F8) { TSheet_field * sh = row_mask.get_sheet(); if (sh != NULL) { TGestione_preventivo_msk & mask = (TGestione_preventivo_msk &) sh->mask(); TDocumento & doc = mask.doc(); const int row = sh->selected(); TCond_vendita & condv = mask.condv(); condv.set_testa(&mask); condv.set_riga(&row_mask); condv.ricerca(); doc[row + 1].put(RDOC_PREZZO, row_mask.get(FR_PREZZO)); doc[row + 1].put(RDOC_PPROV, condv.get_prov()); row_mask.reset(FR_JOLLY2); row_mask.field(FR_JOLLY2).set_focusdirty(false); } } if (k == K_TAB && f.focusdirty()) { row_mask.reset(FR_JOLLY2); row_mask.field(FR_JOLLY2).set_focusdirty(false); } } return true; } bool TGestione_preventivo_msk::pe_costo_handler(TMask_field& f, KEY k) { TMask& row_mask = f.mask(); const bool last_level = row_mask.field(FR_JOLLY3).enabled(); if (last_level) { if (k == K_TAB && f.focusdirty()) { row_mask.reset(FR_JOLLY2); row_mask.field(FR_JOLLY2).set_focusdirty(false); } } return true; } //metodo che setta gli handler sui campi di riga void TGestione_preventivo_msk::user_set_row_handler(TMask& rm, short field, int index) { switch(index) { case 5101: rm.set_handler(field, pe_codart_handler); break; case 5102: rm.set_handler(field, pe_qta_handler); break; default : TDocumento_mask::user_set_row_handler(rm, field, index); break; } } //metodo che setta l'handler di bolla void TGestione_preventivo_msk::user_set_handler( short fieldid, int index) { switch(index) { case 5101: set_field_handler(fieldid, pe_data_handler); break; default : TDocumento_mask::user_set_handler(fieldid, index); break; } } bool TGestione_preventivo_msk::new_revision(const char* codnum, long& ndoc) const { const TCodice_numerazione& num = cached_numerazione(codnum); const int revlen = num.revision_len(); if (revlen > 0) { real fattore = exp10(revlen); fattore.round(0); const long divisore = fattore.integer(); const long newndoc = ndoc + 1; // Obfuscated C contest: forse bastava scrivere questo // if (newndoc/divisore != ndoc/divisore) if (((newndoc / divisore) - (ndoc / divisore)) != 0) return false; else { ndoc = newndoc; return true; } } return false; } TGestione_preventivo_msk::TGestione_preventivo_msk(const char* tipodoc) : TDocumento_mask(tipodoc), _clipboard_row(-1) { //TConfig* configpe = new TConfig(CONFIG_DITTA, "pe"); // A cosa serve? sfield(F_SHEET).set_notify( ss_notify ); _rule = color_rules().add(new TColor_rule("Livello", "", _numexpr, COLOR_BLUE, FOCUS_COLOR)); TFilename pn; doc().tipo().profile_name(pn); TConfig prof(pn, "MAIN"); _field_costo = prof.get("FieldCosto", NULL, -1, "VAR"); } ////////////////////////////////////////// //// CLASSE TGESTIONE_PREVENTIVO_APP //// ////////////////////////////////////////// //ridefinisco il metodo get_mask delle TMotore_application TMask* TGestione_preventivo_app::get_mask( int mode ) { if (mode == MODE_INS || mode == MODE_MOD) { TString4 tipodoc; if (mode == MODE_MOD) tipodoc = get_relation()->curr().get(DOC_TIPODOC); // Lo prendo dalla relazione (Gelai) else tipodoc = TMotore_application::get_mask(MODE_QUERY)->get(F_TIPODOC); if (_doc_masks.objptr(tipodoc) == NULL) { TGestione_preventivo_msk* m = new TGestione_preventivo_msk(tipodoc); _doc_masks.add(tipodoc, m); const TTipo_documento& tdoc = m->doc().tipo(); const TString_array& handlers = tdoc.handlers(); FOR_EACH_ARRAY_ROW(handlers, i, row) { m->user_set_handler( row->get_int( 0 ), row->get_int( 1 ) ); } TSheet_field & sh = m->sfield(F_SHEET); const int y = m->sh_y() - 1; if (m->var_cost()) m->add_list(F_TIPO_COSTO, sh.page(), "Tipo costo", 2, y - 1, 20, "", "1|2|4|5|6", "Ultimo costo|Media ultimi costi|Costo standard|Costo medio|Costo medio ponder."); m->add_button(F_LOAD_COSTS, sh.page(), "Costi", 66, y - 2, 4, 1, ""); m->set_handler(F_LOAD_COSTS, TGestione_preventivo_msk::pe_update_costi_handler); m->add_button(F_REVISION, sh.page(), "Rev.", 73, y - 2, 4, 1, ""); m->set_handler(F_REVISION, TGestione_preventivo_msk::pe_new_revision_handler); m->add_button(F_SHRINK_ALL, sh.page(), "--", 61, y - 1, 1, 1, "", BMP_DARROWU); m->set_handler(F_SHRINK_ALL, TGestione_preventivo_msk::pe_espandi_handler); m->add_button(F_ZOOM_ALL, sh.page(), "++", 66, y -1, 1, 1, "", BMP_DARROWD); m->set_handler(F_ZOOM_ALL, TGestione_preventivo_msk::pe_espandi_handler); m->add_button(F_SHRINK_ROW, sh.page(), "-", 71, y - 1, 1, 1, "", BMP_SARROWU); m->set_handler(F_SHRINK_ROW, TGestione_preventivo_msk::pe_espandi_riga_handler); m->add_button(F_ZOOM_ROW, sh.page(), "+", 76, y -1, 1, 1, "", BMP_SARROWD); m->set_handler(F_ZOOM_ROW, TGestione_preventivo_msk::pe_espandi_riga_handler); TBoolean_field & fk = m->add_boolean(F_USEK, sh.page(), "", 2, y); fk.set_field(DOC_USEK); // m->set_handler(F_USEK, TGestione_preventivo_msk::pe_usek_handler); TToken_string * fk_false = fk.message(0, true); TToken_string * fk_true = fk.message(1, true); *fk_false << "CLEAR," << F_K; *fk_true << "ENABLE," << F_K; TEdit_field & k = m->add_string(F_K, sh.page(), "K ", 5, y, 25); k.set_field(DOC_K); m->add_number(F_LIVELLO, sh.page(), "Livello Succ. ", 33, y, 1); m->add_boolean(F_DETTAGLIO, sh.page(), "Dettaglia", 53, y); m->add_button(F_COPIA_TUTTO, sh.page(), "~Tutto", 66, y, 1, 1, "", BMP_FILECHK); m->set_handler(F_COPIA_TUTTO, TGestione_preventivo_msk::pe_copia_handler); m->add_button(F_COPIA, sh.page(), "~Copia", 71, y, 1, 1, "", BMP_COPY); m->set_handler(F_COPIA, TGestione_preventivo_msk::pe_copia_handler); m->add_button(F_INCOLLA, sh.page(), "~Incolla", 76, y, 1, 1, "", BMP_PASTE); m->set_handler(F_INCOLLA, TGestione_preventivo_msk::pe_incolla_handler); sh.enable_column(sh.cid2index(FR_JOLLY1), false); sh.enable_column(sh.cid2index(FR_JOLLY4), false); } } return TMotore_application::get_mask(mode); } bool TGestione_preventivo_app::last_doc(char provv, int anno, const char* codnum, long& ndoc, TDate& ddoc) const { bool ok = TMotore_application::last_doc(provv, anno, codnum, ndoc, ddoc); const TCodice_numerazione& num = cached_numerazione(codnum); const int revlen = num.revision_len(); if (revlen > 0) { real fattore = exp10(revlen); fattore.round(0); const long divisore = fattore.integer(); if (ok) ndoc /= divisore; else ndoc = 1; ndoc++; ndoc *= divisore; return true; } return ok; } //ridefinisco il metodo write delle TMotore_application int TGestione_preventivo_app::write( const TMask& m ) { TGestione_preventivo_msk & mask = (TGestione_preventivo_msk &) m; TDocumento& doc = mask.doc(); const int rows = doc.physical_rows(); const TString k = doc.get(DOC_K); for (int i = rows ; i > 0; i--) { TRiga_documento & row = (TRiga_documento &)doc[i]; const int level = row.get_int(RDOC_LEVEL); const TString & row_k = row.get(RDOC_K); if ((row_k.blank()) && (i == rows || level >= doc[i + 1].get_int(RDOC_LEVEL))) row.put(RDOC_K, k); } mask.update_costi_ricavi(); return TMotore_application::write(m); } //ridefinisco il metodo rewrite delle TMotore_application int TGestione_preventivo_app::rewrite( const TMask& m ) { TGestione_preventivo_msk & mask = (TGestione_preventivo_msk &) m; TDocumento& doc = ((TDocumento_mask&) m).doc(); const int rows = doc.physical_rows(); const TString k = doc.get(DOC_K); for (int i = rows ; i > 0; i--) { TRiga_documento & row = (TRiga_documento &)doc[i]; const int level = row.get_int(RDOC_LEVEL); const TString & row_k = row.get(RDOC_K); if ((row_k.blank()) && (i == rows || level >= doc[i + 1].get_int(RDOC_LEVEL))) row.put(RDOC_K, k); } mask.update_costi_ricavi(); return TMotore_application::rewrite(m); } //ridefinisco il metodo read della TMotore_application int TGestione_preventivo_app::read(TMask& m) { const int err = TMotore_application::read(m); if (err == NOERR) { TDocumento_mask& mask = (TDocumento_mask&) m; TDocumento& doc = mask.doc(); const TString k = doc.get(DOC_K); TSheet_field & sh = mask.sfield(F_SHEET); for (int i = 1 ; i <= doc.physical_rows(); i++) if (k == doc[i].get(RDOC_K)) { doc[i].zero(RDOC_K); TToken_string & r = sh.row(i - 1); r.add("", sh.cid2index(FR_JOLLY2)); } } return err; } //ridefinisco il metodo init_insert_mode della TMotore_application void TGestione_preventivo_app::init_insert_mode(TMask &m) { m.disable(F_REVISION); m.enable(F_LOAD_COSTS); return TMotore_application::init_insert_mode(m); } void TGestione_preventivo_app::init_modify_mode(TMask &m) { TGestione_preventivo_msk& mask = (TGestione_preventivo_msk&) m; const TDocumento& d = mask.doc(); const TCodice_numerazione& num = d.codice_numerazione(); mask.enable(F_REVISION, !d.bloccato() && num.revision_len() > 0); mask.enable(F_LOAD_COSTS, !d.bloccato()); return TMotore_application::init_modify_mode(m); } int pe0400( int argc, char* argv[]) { TGestione_preventivo_app a; a.run( argc, argv, TR("Gestione Preventivi")); return 0; }