#include #include #include #include #include #include #include "ce0.h" #include "ce2101.h" #include "celib.h" #include "ce0500a.h" #include "../cg/cglib01.h" #include #include "cespi.h" #include "salce.h" #include "ammce.h" //------------------------------------------------------------------- // MASCHERA VIRTUALE //------------------------------------------------------------------- class TBasic_cespi_mask : public TAutomask { protected: int create_fields(int x, int y, short key_id, const int page); TBasic_cespi_mask(const char* name) : TAutomask(name) {} }; int TBasic_cespi_mask::create_fields(int x, int y, short key_id, const int page) { TRectype rec_cespi(LF_CESPI); //cicla sui campi user (se ci sono) nel ditta.ini facendoli apparire sulla pagine Personalizz. TConfig config (CONFIG_DITTA, "ce"); int i = 0; int maxprompt = 0; for (i = 0; config.exist("USER", i); i++) { TToken_string riga = config.get("USER", NULL, i); const TString80 prompt = riga.get(1); const int len = prompt.len(); if (len > maxprompt) maxprompt = len; } maxprompt++; for (i = 0; config.exist("USER", i); i++) { TToken_string riga = config.get("USER", NULL, i); const bool search = riga.get_char(3) == 'X'; //se e' in pagina di ricerca ed il campo non e' di ricerca lo salta! if (page == 0 && !search) continue; //tutto il resto lo fa comunque,settandondolo nella page corretta const short kid = key_id+i; //numero del campo come definito nel .h della maschera const TString16 name = riga.get(0); //nome campo TString80 prompt = riga.get(1); prompt.left_just(maxprompt); //prompt sulla maschera const TString80 picture = riga.get(2); //picture del campo(se c'e') //se la lunghezza del campo non e' definita nella picture la prende dal tracciato const int len = picture.blank() ? rec_cespi.length(name) : picture.len(); //chiede al record di che tipo e' il campo chiamato name... const TFieldtypes tipo_campo = rec_cespi.type(name); //..quanto e' lungo...(maniaca!) const int length_campo = rec_cespi.length(name); //...e quanti decimali ha nel caso sia un real int ndec_campo = 0; if (tipo_campo == _realfld) ndec_campo = rec_cespi.ndec(name); const bool btn = search && page == 0; //crea finalmente i nuovi campi sulla pagina 1 (Personalizzazioni) switch(tipo_campo) { case _wordfld: add_number (kid, page, prompt, x, i+y, len, btn ? "BU" : "U"); break; case _intfld : case _longfld: add_number (kid, page, prompt, x, i+y, len, btn ? "B" : ""); break; case _intzerofld: case _longzerofld: add_number (kid, page, prompt, x, i+y, len, btn ? "BZ" : "Z"); break; case _realfld: add_number (kid, page, prompt, x, i+y, len, "", ndec_campo); break; case _datefld: add_date (kid, page, prompt, x, i+y, btn ? "B" : ""); break; case _memofld: add_zoom(kid, page, prompt, x, i+y, 50); break; default : add_string (kid, page, prompt, x, i+y, len, btn ? "BU" : ""); break; } //deve poter salvare il contenuto nei campi!! (e' il FIELD delle maschere) TEdit_field& efld = efield(kid); efld.set_field(name); //la set_field lo fa } //deve accendere gli handler di questa maschera perche' funzionino set_handlers(); return i; } //------------------------------------------------------------------- // MASCHERA RICERCA (ce0500a) //------------------------------------------------------------------- class TQuery_mask : public TBasic_cespi_mask { int _staat; protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); void on_search_event(TOperable_field& o); void on_user_search(TOperable_field& o); virtual void on_firm_change(); int calcola_stato_attivita(); bool cespite_ok() const; void set_cespi_filter(); public: int stato_attivita() const { return _staat; } TQuery_mask(); }; void TQuery_mask::on_user_search(TOperable_field& o) { TToken_string order, header; const TFieldref* campo = o.field(); const TString nome_campo = campo->name(); //ordinare per campo personalizzato/idcespite/descrizione order.add(nome_campo); TString prompt = o.prompt(); prompt << "@" << o.size(); //lunghezza del prompt del campo header.add(prompt); order.add(CESPI_IDCESPITE); header.add(TR("Cespite@10")); order.add(CESPI_DESC); header.add(FR("Descrizione cespite@50")); TRelation rel(LF_CESPI); TSorted_cursor cur(&rel, order); TToken_string siblings; TBrowse_sheet sht(&cur, order, TR("Cespiti"), header, 0, (TEdit_field&)o, siblings); if (sht.run() == K_ENTER) { TToken_string& row = sht.row(); set(F_IDCESPITE, row.get(1), true); stop_run(K_AUTO_ENTER); } } void TQuery_mask::on_search_event(TOperable_field& o) { TToken_string order, fields, header; if (o.dlg() >= F_SEARCH3) { order.add(CESPI_STABILIM); header.add(HR("Stabilimento")); order.add(CESPI_REPARTO); header.add(HR("Reparto@10")); } if (o.dlg() >= F_SEARCH2) { order.add(CESPI_CODIMP); header.add(HR("Impianto@10")); order.add("CIM->S0"); header.add(HR("Descrizione impianto@40")); } if (o.dlg() >= F_SEARCH1) { order.add(CESPI_CODCAT); header.add(HR("Cat")); order.add(CESPI_DTCOMP); header.add(HR("Data Acq.@10")); } order.add(CESPI_IDCESPITE); header.add(HR("Codice@10")); fields = order; fields.add(CESPI_DESC); header.add(HR("Descrizione cespite@50")); TRelation rel(LF_CESPI); rel.add("CIM","CODTAB==CODIMP"); TString filter; if (get(F_SELECT) == "I") // Filtro per impianto { const TString& imp = get(F_IMPIANTO); if (!imp.empty()) filter << CESPI_CODIMP << "=\"" << imp << '"'; } else // Filtro per attività { filter << "STR(" << CESPI_CODCGRA << "=" << get_int(F_GRUPPO) << ')'; filter << "&&(" << CESPI_CODSPA << "=\"" << get(F_SPECIE) << "\")"; } TSorted_cursor cur(&rel, order, filter); TCursor_sheet sht(&cur, order, TR("Cespiti"), header, 0, 1); if (sht.run() == K_ENTER) { TToken_string& row = sht.row(); const int cod_pos = row.items()-2; set(F_IDCESPITE, row.get(cod_pos), true); stop_run(K_AUTO_ENTER); } } int TQuery_mask::calcola_stato_attivita() { const int ese = get_int(F_ESERCIZIO); const int gru = get_int(F_GRUPPO); const char* spe = get(F_SPECIE); TString16 str; str.format("%04d%02d%-4s", ese, gru, spe); const TRectype& curr_ccb = cache().get("CCB", str); if (curr_ccb.get_bool("B1")) // Bollato stampato _staat = 3; else { TEsercizi_contabili esc; str.format("%04d%02d%-4s", esc.pred(ese), gru, spe); const TRectype& prev_ccb = cache().get("CCB", str); _staat = prev_ccb.get_bool("B1") ? 2 : 1; } TDitta_cespiti& dc = ditta_cespiti(); dc.set_attivita(ese, gru, spe); return _staat; } bool TQuery_mask::cespite_ok() const { const TRectype & cespi = cache().get(LF_CESPI, get(F_IDCESPITE)); const bool ok = !cespi.empty(); return ok; } void TQuery_mask::set_cespi_filter() { TString filter; if (get(F_SELECT) == "I") // Filtro per impianto { const TString& imp = get(F_IMPIANTO); if (!imp.empty()) filter << CESPI_CODIMP << "=\"" << imp << '"'; } else // Filtro per attività { filter << "STR(" << CESPI_CODCGRA << "=" << get_int(F_GRUPPO) << ')'; filter << "&&(" << CESPI_CODSPA << "=\"" << get(F_SPECIE) << "\")"; } efield(F_IDCESPITE).browse()->set_filter(filter); efield(F_DESC).browse()->set_filter(filter); } bool TQuery_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case F_ESERCIZIO: case F_GRUPPO: case F_SPECIE: if (e == fe_init || e == fe_modify) { const bool can_create = calcola_stato_attivita() != 3; // Bollato non stampato enable(DLG_NEWREC, can_create && !field(F_SPECIE).empty() && !field(F_CATEGORIA).empty()); enable(DLG_DELREC, can_create); set_cespi_filter(); } break; case F_SELECT: case F_IMPIANTO: if (e == fe_modify) set_cespi_filter(); break; case F_SEARCH1: case F_SEARCH2: case F_SEARCH3: if (e == fe_button) on_search_event(o); break; case F_CATEGORIA: case F_DESC_CAT: { TDitta_cespiti& dc = ditta_cespiti(); bool ok = dc.on_category_event(o, e, jolly); if (ok) { if (e == fe_modify && !o.empty() && stato_attivita() == 2) { const TRectype& cac = dc.categoria(0, NULL, get_int(F_CATEGORIA)); const int fine_validita = cac.get_date("D1").year(); if (fine_validita > 0 && fine_validita < get_int(F_ESERCIZIO)) return error_box(FR("Categoria scaduta nell'esercizio %d"), fine_validita); } if (e == fe_init || e == fe_modify || e == fe_button) { const bool bollati = stato_attivita() == 3; enable(DLG_NEWREC, !bollati && !o.empty() && !field(F_SPECIE).empty()); } if (e == fe_close && o.empty() && !field(F_IDCESPITE).empty() && !cespite_ok()) return error_box(TR("È necessario specificare la categoria del nuovo cespite")); } } break; case F_IDCESPITE: if (e == fe_close) { if (stato_attivita() == 3 && !cespite_ok()) return error_box(TR("E' stato stampato il bollato dell'anno:\nnon sono permessi inserimenti")); } if (e == fe_modify && !o.empty() && cespite_ok()) { TString key; key = get(F_IDCESPITE); key << '|' << get(F_ESERCIZIO) << "|1"; const TRectype & salce = cache().get(LF_SALCE, key); if (salce.empty()) return yesno_box(TR("Non esistono saldi per l'anno selezionato:\nSi desidera continuare ugualmente?")); } break; case F_USER: case F_USER+1: case F_USER+2: case F_USER+3: case F_USER+4: case F_USER+5: if (e == fe_button) on_user_search(o); break; default: break; } return true; } void TQuery_mask::on_firm_change() { TAutomask::on_firm_change(); ditta_cespiti().init_mask(*this); } TQuery_mask::TQuery_mask() : TBasic_cespi_mask("ce0500a") { first_focus(F_IDCESPITE); create_fields(2, 13, F_USER, 0); } //------------------------------------------------------------------- // MASCHERA DI MODIFICA (ca0500b) //------------------------------------------------------------------- class TEdit_mask : public TBasic_cespi_mask { TTipo_cespite _tipo; int _staat; protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); virtual bool on_key(KEY k); bool one_compiled(const short* f) const; TCurrency sum_fields(const short* f) const; bool test_ammissibilita_dati(); bool test_ammissibilita_saldi(); bool test_ammissibilita_fondi(); public: void set_stato_attivita(int sa) { _staat = sa; } int stato_attivita() const { return _staat; } void set_tipo_cespite(TTipo_cespite tc) { _tipo = tc; } TTipo_cespite tipo_cespite() const { return _tipo; } void protect_page(int page, TToken_string& enabling); TEdit_mask(); }; bool TEdit_mask::one_compiled(const short* f) const { int i; for (i = 0; f[i]; i++) { if (!field(f[i]).empty()) break; } return f[i] > 0; } TCurrency TEdit_mask::sum_fields(const short* f) const { TCurrency sum, val; for (int i = 0; f[i] != 0; i++) { get_currency(abs(f[i]), val); if (f[i] > 0) sum += val; else sum -= val; } return sum; } bool TEdit_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { bool ok = true; switch (o.dlg()) { case F_CATEGORIA: if (e == fe_init) { TDitta_cespiti& dc = ditta_cespiti(); dc.on_category_event(o, e, jolly); } break; case F_DTCOMP: if (e == fe_init && o.empty()) { TConfig ini (CONFIG_DITTA, "ce"); TString16 datamov = ini.get("DataMovimento"); if (datamov.empty()) datamov = TDate(TODAY).string(); o.set(datamov); } if (e == fe_modify || e == fe_close) { const TDate dtcomp(o.get()); TDitta_cespiti& dc = ditta_cespiti(); TDate iniz, fine; dc.esercizio_corrente(iniz, fine); if (stato_attivita() == 2) { // if (m.dtcomp < iniz) // Errore 0000820: test inutile // return error_box(TR("La data appartiene ad un esercizio già stampato su bollato")); const TRectype& cac = dc.categoria(0, NULL, get_int(F_CATEGORIA)); iniz = cac.get("D0"); if (iniz.ok() && dtcomp < iniz) return error_box(TR("La data è precedente all'inizio della validità della categoria")); fine = cac.get("D1"); if (fine.ok() && dtcomp > fine) return error_box(TR("La data è succesiva alla fine della validità della categoria")); } if (dc.esercizio_costituzione() && dtcomp < iniz) return error_box(TR("Non è possibile specificare una data antecedente all'esercizio di costituzione")); if (tipo_cespite() != tc_materiale && dtcomp.year() >= dc.anno_tuir()) { if (field(F_DTFUNZ).empty()) set(F_DTFUNZ, o.get()); } } break; case F_DTFUNZ: if (e == fe_modify || e == fe_close) { const TDate dtfunz(o.get()); if (dtfunz.ok()) { const TDate dtcomp(field(F_DTCOMP).get()); if (dtfunz < dtcomp) return error_box(FR("La data di entrata in funzione deve essere successiva a quella di aquisizione")); if (!dtcomp.ok()) return error_box(TR("La data di entrata in funzione non puo' essere inserita senza specificare quella di aquisizione")); if (stato_attivita() == 2) { const TDate iniz(get(F_INIZIO_ES)); if (dtfunz < iniz) return error_box(TR("La data di entrata in funzione deve essere successiva a quella di inizio esercizio")); } TDitta_cespiti& dc = ditta_cespiti(); if (_tipo != tc_materiale && dtfunz != dtcomp) { if (dtcomp.year() >= dc.anno_tuir()) return error_box(TR("In base alla normativa del TUIR, le date di acquisizione e di entrata in funzione devono coincidere")); } const TRectype& cac = dc.categoria(0, NULL, get_int(F_CATEGORIA)); const TDate iniz = cac.get_date("D0"); if (iniz.ok() && dtfunz < iniz) return error_box(TR("La data è precedente all'inizio validità della categoria")); const TDate fine = cac.get_date("D1"); if (fine.ok() && dtfunz > fine) return error_box(TR("La data è successiva alla fine validità della categoria")); if (dtfunz.year() >= dc.anno_tuir()) set(F_TUIR, "X"); else reset(F_TUIR); } } break; case F_QUADRATURA: if (e == fe_button) { set(F_NORMALE2, get(F_NORMALE)); set(F_NORMALE3, get(F_NORMALE)); set(F_ACCELERATO2, get(F_ACCELERATO)); set(F_ACCELERATO3, get(F_ACCELERATO)); set(F_ANTICIPATO2, get(F_ANTICIPATO)); set(F_ANTICIPATO3, get(F_ANTICIPATO)); } break; case F_VNONAMM: if (e == fe_modify || e == fe_close) { if (o.empty() && get_bool(F_LEASING)) return error_box(TR("Indicare il valore del riscatto per beni in leasing")); test_ammissibilita_saldi(); } break; case F_PLUSREIN: if ((e == fe_modify || e == fe_close) && !o.empty()) { TCurrency costo; get_currency(F_COSTO, costo); TCurrency noamm; get_currency(F_VNONAMM, noamm); TCurrency plusr; get_currency(F_PLUSREIN, plusr); const TCurrency minim = costo - noamm; if (plusr > minim) return error_box(FR("La plusvalenza reinvestita non puo' superare %s"), minim.string(true)); } break; case F_ELEMENTI: if ((e == fe_modify || e == fe_close) && o.empty()) { const TDate dtcomp(field(F_DTCOMP).get()); const TDate dtiniz(field(F_INIZIO_ES).get()); if (dtcomp.ok() && dtcomp < dtiniz) return error_box(TR("E' necessario specificare il numero di elementi per cespiti acquisiti negli esercizi precedenti")); const short fields[] = { F_COSTO, F_VNONAMM, F_RIV75, F_RIV83, F_RIV90, F_RIV91, F_RIVGF, F_RIVGC, 0 }; if (one_compiled(fields)) return error_box(TR("E' necessario inserire il numero degli elementi")); } break; case F_RIV90: case F_RIV91: if ((e == fe_init || e == fe_modify) && o.active()) { TEdit_field& anni = efield(o.dlg()+1); if (o.empty()) { anni.reset(); anni.disable(); } else anni.enable(); } break; case F_ANNIAMM: if (e == fe_init || e == fe_modify) enable_page(3, !o.empty()); break; case F_NORMALE: if (e == fe_close) { const short fv[] = { F_COSTO, -F_VNONAMM, F_RIV75, F_RIV83, F_RIV90, F_RIV91, F_RIVGF, 0 }; const short fa[] = { F_NORMALE, F_ACCELERATO, F_ANTICIPATO, F_QPERSE, F_FPRIVATO, F_QPERSEPRIV, 0 }; const TCurrency val_amm = sum_fields(fv); const TCurrency fon_amm = sum_fields(fa); if (fon_amm > val_amm) { TString msg; msg << TR("Il fondo ammortamento fiscale (") << fon_amm.string(true) << ')'; msg << TR("non puo' superare il valore da ammortizzare (") << val_amm.string(true) << ')'; return error_box(msg); } } break; case F_FPRIVATO: if (e == fe_close) { if (get_int(F_USOPROM) > 1 && !field(F_ANNIAMM).empty()) { if (field(F_FPRIVATO).empty() && field(F_QPERSEPRIV).empty()) return error_box(TR("E' necessario inserire un fondo di ammortamento privato o delle quote perse private")); } } break; case F_NORMALE2: if (e == fe_close) { const short fv[] = { F_COSTO, F_RIV75, F_RIV83, F_RIV90, F_RIV91, F_RIVGC, 0 }; const short fa[] = { F_NORMALE2, F_ACCELERATO2, F_ANTICIPATO2, 0 }; const TCurrency val_amm = sum_fields(fv); const TCurrency fon_amm = sum_fields(fa); if (fon_amm > val_amm) { TString msg; msg << TR("Il fondo ammortamento civilistico (") << fon_amm.string(true) << ')'; msg << TR("non puo' superare il valore da ammortizzare (") << val_amm.string(true) << ')'; return error_box(msg); } } break; case F_VEIDIP: case F_VEICOLO: //testa se e' un veicolo promiscuo in uso a dipendente if (e == fe_init || e == fe_modify) { const bool veicolodipendente = get_bool(F_VEIDIP); //navi,aerei,astronavi etc. non possono godere del fringe benefit const int tipoveicolo = get_int(F_VEICOLO); enable(F_FRINGEBEN, veicolodipendente && tipoveicolo > 1 && tipoveicolo < 5); } break; case F_MATRICOLE: if (e == se_notify_modify) { TSheet_field& sf = sfield(F_MATRICOLE); const TString80 matricola = sf.cell(jolly, 0); if (matricola.blank()) return error_box(TR("Matricola nulla!")); TISAM_recordset multirel("USE MULTIREL KEY 2\nSELECT FIRST!=#IDCESPITE\nFROM COD=CEMAT SECOND=#MATRICOLA\nTO COD=CEMAT SECOND=#MATRICOLA"); multirel.set_var("#MATRICOLA", TVariant(matricola)); multirel.set_var("#IDCESPITE", TVariant(get(F_IDCESPITE))); const TRecnotype items = multirel.items(); if (items > 0) { TString msg; msg << TR("Matricola gia' utilizzata nel cespite ") << multirel.get(MULTI_FIRST); return error_box(msg); } FOR_EACH_SHEET_ROW(sf, i, row) if(i != jolly) { if (matricola == row->get(0)) { TString msg; msg << TR("Matricola gia' utilizzata alla riga ") << (i+1); return error_box(msg); } } } break; default: break; } return ok; } // Disabilita tutti i campi della pagina "page" (1 based) tranne quelli nella lista "enabling" void TEdit_mask::protect_page(int page, TToken_string& enabling) { // Determina l'id del primo campo della pagina short cid = 0; switch (page) { case 2: cid = F_ELEMENTI; break; // Pagina 2 (Saldi) case 3: cid = F_NORMALE; break; // Pagina 3 (Fondi) default: cid = F_IDCESPITE; break; // Pagina 0 (Cespite) } // Determina l'handle della pagina selezionata WINDOW parent = field(cid).parent(); for (int f = fields()-1; f >= 0; f--) { TMask_field& c = fld(f); if (c.parent() == parent) // Il campo appartiene alla pagina voluta? { const short id = c.dlg(); if (id > 100 && id < 1000 && c.is_operable() && c.enabled_default()) { const bool on = enabling.empty() || enabling.get_pos(c.dlg()) >= 0; c.enable(on); if (cid == id) // Ho raggiunto il capo pagina? break; } } } } bool TEdit_mask::test_ammissibilita_dati() { const char* msg = insert_mode() ? TR("Inserimento") : TR("Modifica"); xvtil_statbar_set(msg, true); return false; } bool TEdit_mask::test_ammissibilita_saldi() { bool protez = false; const char* msg = ""; switch (_staat) { case 1: case 2: { const TDate iniz(get(F_INIZIO_ES)); const TDate dtacq(get(F_DTCOMP)); const TDate dtfunz(get(F_DTFUNZ)); if (!dtacq.ok() || !dtfunz.ok()) protez = true; else protez = dtacq >= iniz || dtfunz >= iniz; if (protez) msg = TR("Inserire gli importi nel movimento d'acquisto"); } break; case 3: protez = true; msg = TR("Bollato stampato: non sono ammesse modifiche"); break; default: break; } TToken_string enabling; if (protez) enabling = "883"; // Disabilita tutto! protect_page(2, enabling); if (*msg) beep(1); else msg = insert_mode() ? TR("Inserimento") : TR("Modifica"); xvtil_statbar_set(msg, true); return protez; } bool TEdit_mask::test_ammissibilita_fondi() { bool protez = false; const char* msg = ""; switch (_staat) { case 1: case 2: { const TDate dtacq(get(F_DTCOMP)); const TDate dtfunz(get(F_DTFUNZ)); if (!dtacq.ok() || !dtfunz.ok()) protez = true; else { const TDate iniz(get(F_INIZIO_ES)); protez = dtacq >= iniz; } if (protez) msg = TR("Inserire gli importi nel movimento d'acquisto"); } break; case 3: protez = true; msg = TR("Bollato stampato: non sono ammesse modifiche"); break; default: protez = false; break; } TToken_string enabling; if (protez) enabling = "883"; // Disabilita tutto! protect_page(3, enabling); if (!protez) { const TDate dtfunz(get(F_DTFUNZ)); const TDate iniz(get(F_INIZIO_ES)); bool prot9 = false; if (!dtfunz.ok() || dtfunz >= iniz) { msg = TR("Cespite non ancora entrato in funzione a inizio esercizio"); prot9 = true; } else { const TRectype& cac = ditta_cespiti().categoria(0, NULL, get_int(F_CATEGORIA)); if (cac.get_bool("B0")) { msg = TR("Categoria non ammortizzabile"); prot9 = true; } } enable(-9, !prot9); //testa se e' un veicolo promiscuo in uso a dipendente if (!prot9) { const bool veicolodipendente = get_bool(F_VEIDIP); //navi,aerei,astronavi etc. non possono godere del fringe benefit const int tipoveicolo = get_int(F_VEICOLO); enable(F_FRINGEBEN, veicolodipendente && tipoveicolo > 1 && tipoveicolo < 5); } } if (*msg) beep(1); else msg = insert_mode() ? TR("Inserimento") : TR("Modifica"); xvtil_statbar_set(msg, true); return protez; } bool TEdit_mask::on_key(KEY k) { // Try to predict next page! const int old_page = curr_page()+1; int new_page = old_page; switch (k) { case K_CTRL+K_F1: new_page = 1; break; case K_CTRL+K_F2: new_page = 2; break; case K_CTRL+K_F3: new_page = 3; break; case K_CTRL+K_F4: new_page = 4; break; case K_PREV : new_page--; break; case K_NEXT : new_page++; break; default: break; } // If page will change ... if (old_page != new_page) switch(new_page) { case 1: test_ammissibilita_dati(); break; case 3: test_ammissibilita_saldi(); break; case 4: test_ammissibilita_fondi(); break; default: break; } return TAutomask::on_key(k); } TEdit_mask::TEdit_mask() : TBasic_cespi_mask("ce0500b") { create_fields(1, 13, F_USER, 1); } //-------------------------------------------------------------- // APPLICAZIONE //-------------------------------------------------------------- class TAnacespi : public TRelation_application { TRelation* _cespiti; int _rel_year; TAssoc_array _matricole_iniziali; TQuery_mask* _qmask; TEdit_mask* _emask; private: void init_mask(TMask& m); bool kill_cespite(const TString& idcespite, int lfile, int key = 1); protected: // @cmember Inizializzazione dei dati dell'utente virtual bool user_create(); // @cmember Distruzione dei dati dell'utente virtual bool user_destroy(); virtual bool changing_mask(int mode); // @cmember Richiede la maschera da usare virtual TMask* get_mask(int mode); // @cmember Ritorna la relazione da modificare virtual TRelation* get_relation() const; virtual const char* get_next_key(); virtual bool protected_record(TRectype& rec); virtual void init_query_mode(TMask& m); virtual void init_insert_mode(TMask& m); virtual void init_modify_mode(TMask& m); void leggi_matricole(TMask& m); void aggiorna_matricole(const TMask& m); virtual int read(TMask& m); virtual int rewrite(const TMask& m); virtual int write(const TMask& m); virtual bool remove(); }; bool TAnacespi::changing_mask(int) { return true; } TMask* TAnacespi::get_mask(int mode) { return mode == MODE_QUERY ? (TMask*)_qmask : (TMask*)_emask; } // get_relation più complessa della storia di campo TRelation* TAnacespi::get_relation() const { const int year = _qmask->get_int(F_ESERCIZIO); TRelation*& csp = ((TAnacespi*)this)->_cespiti; if (year != _rel_year && csp != NULL) { delete csp; csp = NULL; } if (csp == NULL) { // Crea nuova relazione su cespi csp = new TRelation(LF_CESPI); ((TAnacespi*)this)->_rel_year = year; // Memorizza anno utilizzato // Collega salce TString80 expr1; expr1 << SALCE_IDCESPITE << "==" << CESPI_IDCESPITE; expr1 << '|' << SALCE_CODES << "==" << year; expr1 << '|' << SALCE_TPSALDO << "==1"; csp->add(LF_SALCE, expr1); // Collega i tre tipi di ammce for (int a = 1; a <= 3; a++) { TString80 expr2 = expr1; expr2 << '|' << AMMCE_TPAMM << "==" << a; csp->add(LF_AMMCE, expr2, 1, 0, a-1); } // Attiva il salvataggio anche di salce e ammce csp->write_enable(); } return _cespiti; } void TAnacespi::init_query_mode(TMask& m) { ditta_cespiti().init_mask(m); set_search_field(F_IDCESPITE); } bool TAnacespi::protected_record(TRectype& rec) { const TDate dtalien = rec.get_date(CESPI_DTALIEN); return dtalien.ok(); } void TAnacespi::init_mask(TMask& m) { TDitta_cespiti& dc = ditta_cespiti(); dc.init_mask(m); const bool can_edit = !dc.bollato_stampato() && m.field(F_DTALIEN).empty(); m.enable(DLG_SAVEREC, can_edit); m.enable(DLG_DELREC, can_edit && m.edit_mode()); m.disable(DLG_NEWREC); _emask->set_stato_attivita(_qmask->stato_attivita()); const TRectype& cac = dc.categoria(0, NULL, _qmask->get_int(F_CATEGORIA)); const int tc = cac.get_int("I0"); _emask->set_tipo_cespite(tc==0 ? tc_materiale : (tc==1 ? tc_immateriale : tc_pluriennale)); const bool mat_only = _emask->tipo_cespite() == tc_materiale; m.show(F_LEASING, mat_only); m.show(F_ANNIRIC, true); // m.show(F_ANNIRIC, mat_only); // Sempre visibile m.show(F_USATO, mat_only); m.show(F_AMMPROP, dc.ammortamento_proporzionale()); } void TAnacespi::init_insert_mode(TMask& m) { init_mask(m); m.set(F_TUIR, "X"); if (_emask->tipo_cespite() == tc_materiale) m.set(F_SPEMAN, 2); else { m.set(F_SPEMAN, 1); m.disable(F_SPEMAN); TDitta_cespiti& dc = ditta_cespiti(); const TRectype& cac = dc.categoria(0, NULL, m.get_int(F_CATEGORIA)); m.set(F_ANNIRIC, cac.get("I3")); } m.set(F_ESCLPR, _emask->tipo_cespite() != tc_pluriennale ? "X" : ""); // Extra: non richiesti da analisi, ma obbligatori m.set(F_VEICOLO, 1); m.set(F_USOPROM, 1); //svuota l'assoc_array delle matricole antiche _matricole_iniziali.destroy(); } void TAnacespi::init_modify_mode(TMask& m) { init_mask(m); const int staat = _qmask->stato_attivita(); TToken_string enabling; if (staat == 2 || staat == 3) { TDitta_cespiti& dc = ditta_cespiti(); TDate iniz, fine; dc.esercizio_corrente(iniz, fine); const TDate dtacq = m.get(F_DTCOMP); const TDate dtfunz = m.get(F_DTFUNZ); if (staat == 2) { if (dtacq < iniz) { if (!dtfunz.ok() || dtfunz >= iniz) enabling.add(F_DTFUNZ); if (_emask->tipo_cespite() == tc_materiale) { enabling.add(F_USOPROM); enabling.add(F_VEIDIP); enabling.add(F_VEICOLO); enabling.add(F_SPEMAN); enabling.add(F_FABBR06); } } } else // == 3 { if (!dtfunz.ok() || dtfunz >= iniz) enabling.add(F_DTFUNZ); } } _emask->protect_page(1, enabling); if (staat == 2 || staat == 3) { enabling.cut(0); _emask->protect_page(2, enabling); } if (!m.field(F_DTALIEN).empty()) xvtil_statbar_set(TR("Cespite alienato: non è possibile apportare modifiche"), true); } const char* TAnacespi::get_next_key() { real num = 1; TLocalisamfile cespi(LF_CESPI); if (cespi.last() == NOERR) num = cespi.get_real(CESPI_IDCESPITE) + 1; return format("%d|%s", F_IDCESPITE, num.string()); } void TAnacespi::leggi_matricole(TMask& m) { TSheet_field& sf = m.sfield(F_MATRICOLE); sf.destroy(); //svuota l'assoc_array delle matricole antiche _matricole_iniziali.destroy(); TISAM_recordset cemat("USE MULTIREL\nFROM COD=CEMAT FIRST=#IDCESPITE\nTO COD=CEMAT FIRST=#IDCESPITE"); cemat.set_var("#IDCESPITE", TVariant(m.get(F_IDCESPITE))); for (bool ok = cemat.move_first(); ok; ok = cemat.move_next()) { TToken_string& riga = sf.row(-1); riga = cemat.get(MULTI_SECOND).as_string(); _matricole_iniziali.add(riga); //aggiorna le matricole iniziali riga.add(cemat.get(MULTI_DATA).as_string()); } sf.force_update(); } int TAnacespi::read(TMask& m) { int err = TRelation_application::read(m); //gestione matricole if (err == NOERR) leggi_matricole(m); return err; } void TAnacespi::aggiorna_matricole(const TMask& m) { //aggiorna le matricole confrontando quelle iniziali con quelle rilevate TAssoc_array matricole_attuali; TSheet_field& sf = m.sfield(F_MATRICOLE); FOR_EACH_SHEET_ROW(sf, i, row) matricole_attuali.add(row->get(0)); TLocalisamfile multirel(LF_MULTIREL); FOR_EACH_ASSOC_OBJECT(_matricole_iniziali, h, key, obj) { if (!matricole_attuali.is_key(key)) { multirel.put(MULTI_COD, "CEMAT"); multirel.put(MULTI_FIRST, m.get(F_IDCESPITE)); multirel.put(MULTI_SECOND, key); multirel.remove(); } } FOR_EACH_SHEET_ROW(sf, j, riga) { const TString80 matricola = riga->get(0); if (matricola.full()) { multirel.put(MULTI_COD, "CEMAT"); multirel.put(MULTI_FIRST, m.get(F_IDCESPITE)); multirel.put(MULTI_SECOND, matricola); multirel.put(MULTI_DATA, riga->get(1)); if (_matricole_iniziali.is_key(matricola)) multirel.rewrite(); else multirel.write(); } } } int TAnacespi::rewrite(const TMask& m) { int err = TRelation_application::rewrite(m); if (err == NOERR) aggiorna_matricole(m); return err; } int TAnacespi::write(const TMask& m) { const TDitta_cespiti& dc = ditta_cespiti(); const TRectype& cac = dc.categoria(0, NULL, m.get_int(F_CATEGORIA)); TRectype& curr = get_relation()->curr(); switch (_emask->tipo_cespite()) { case tc_immateriale: if (cac.get_int("I1") == 2) // Percentuali { curr.put(CESPI_PIMM, cac.get("R13")); curr.put(CESPI_VINCOLO, 1); } else // Anni { const int anni = cac.get_int("I3"); ((TMask&)m).set(F_ANNIRIC, anni); curr.zero(CESPI_PIMM); curr.put(CESPI_ANNIRIC, anni); curr.put(CESPI_VINCOLO, 2); } break; case tc_pluriennale: { const int anni = cac.get_int("I3"); ((TMask&)m).set(F_ANNIRIC, anni); curr.put(CESPI_VINCOLO, cac.get("I2")); curr.put(CESPI_PMINP, cac.get("R14")); curr.put(CESPI_PMAXP, cac.get("R15")); curr.put(CESPI_ANNIRIC, anni); } break; default: { TDate dt(m.get(F_DTFUNZ)); if (!dt.ok()) dt = m.get_date(F_INIZIO_ES); // % beni mat D.M. 29/10/74 oppure D.M. 31/12/88 const TString& pmat = cac.get(dt.year() < 1989 ? "R12" : "R11"); curr.put(CESPI_PMAT, pmat); } break; } const int cat = m.get_int(F_CATEGORIA); if (cat > 40) { curr.zero(CESPI_CODCGR); curr.zero(CESPI_CODSP); } else { curr.put(CESPI_CODCGR, m.get(F_GRUPPO)); curr.put(CESPI_CODSP, m.get(F_SPECIE)); } int err = TRelation_application::write(m); //gestione matricole if (err == NOERR) aggiorna_matricole(m); return err; } bool TAnacespi::kill_cespite(const TString& idcespite, int lfile, int key) { TRelation rel(lfile); TRectype& filter = rel.curr(); if (lfile == LF_MULTIREL) { filter.put(MULTI_COD, "CEMAT"); filter.put(MULTI_FIRST, idcespite); } else filter.put("IDCESPITE", idcespite); TCursor cur(&rel, "", key, &filter, &filter); const TRecnotype items = cur.items(); if (items > 0) { cur.freeze(); const TRectype& curr = rel.curr(); for (cur = 0L; cur.pos() < items; ++cur) { int err = curr.remove(rel.lfile()); if (err != NOERR) return error_box(FR("Errore %d di cancellazione sul file %d"), err, lfile); } } return true; } bool TAnacespi::remove() { const int staat = _qmask->stato_attivita(); bool yes = false; if (staat == 3) yes = yesno_box(TR("ATTENZIONE: il cespite è già stato stampato su bollato.\n" "Si desidera confermare l'elimininazione?")); else yes = yesno_box(TR("ATTENZIONE: verranno eliminati anche i valori relativi agli esercizi precedenti.\n" "Si desidera confermare l'elimininazione?")); if (yes) { TRelation* rel = get_relation(); const TString16 idcespite = rel->curr().get(CESPI_IDCESPITE); if (kill_cespite(idcespite, LF_SALCE) && kill_cespite(idcespite, LF_MOVCE, 2) && kill_cespite(idcespite, LF_MOVAM) && kill_cespite(idcespite, LF_AMMMV) && kill_cespite(idcespite, LF_AMMCE) && kill_cespite(idcespite, LF_MULTIREL)) { rel->write_enable(0, false); // Disabilito la cancellazione dei saldi (gia' cancellati prima) yes = TRelation_application::remove(); rel->write_enable(0, true); } } return yes; } bool TAnacespi::user_create() { open_files(LF_TABCOM, LF_TAB, LF_CESPI, LF_SALCE, LF_AMMCE, LF_MOVCE, LF_MOVAM, LF_AMMMV, 0); _cespiti = NULL; _rel_year = 0; _qmask = new TQuery_mask; _emask = new TEdit_mask; return true; } bool TAnacespi::user_destroy() { delete _cespiti; delete _emask; delete _qmask; return true; } int ce0500(int argc, char* argv[]) { TAnacespi a; a.run(argc, argv, TR("Anagrafica cespiti")); return 0; }