// cg5300.cpp // modifica parametri contabilita' relativi alla liquidazione #include #include #include #include #include #include #include #include #include #include "cg5.h" #include "cg5300a.h" #include #include #define TAB_LIA "%LIA" #define TAB_PLA "%PLA" class TParaliq_app : public TRelation_application { TRelation * _rel; TMask * _msk; TLocalisamfile * _attiv; TLocalisamfile * _ditte; int _yearliq; TTable * _pla; protected: // Applicat virtual void on_config_change(); static bool ditta_handler(TMask_field& f, KEY k); static bool gelidi_handler(TMask_field& f, KEY k); static bool agrmin_handler(TMask_field& f, KEY k); static bool credres_handler(TMask_field& f, KEY k); static bool credpreccost_handler(TMask_field& f, KEY k); static bool utcred_handler(TMask_field& f, KEY k); protected: // Relapp virtual bool user_create(); virtual bool user_destroy(); virtual TRelation* get_relation() const { return _rel; } virtual TMask* get_mask(int mode) { return _msk; } virtual bool changing_mask(int mode) { return FALSE; } // file intertface virtual bool remove() { return TRUE; } virtual bool protected_record(TRectype&) { return TRUE; } virtual void init_query_mode(TMask&); virtual void init_insert_mode(TMask& m); virtual void init_modify_mode(TMask& m); virtual int rewrite(const TMask& m); // non si possono aggiungere record, se non ci sono vengono // creati automaticamente virtual int write(const TMask& m) { return rewrite(m);} virtual int read(TMask& m); protected: void check_registers(int year); void init_array(TMask& m, bool update); static bool sheet_action(TSheet_field& s, int r, KEY k); public: TRelation & rel() const { return *_rel;} TParaliq_app() {} virtual ~TParaliq_app() {} }; inline TParaliq_app& app() { return (TParaliq_app&) main_app(); } bool TParaliq_app::ditta_handler(TMask_field& f, KEY k) { if (f.to_check(k)) { TFirm fr(atol(f.get())); f.mask().set(F_CODVAL, fr.codice_valuta()); } return TRUE; } bool TParaliq_app::gelidi_handler(TMask_field& f, KEY k) { if (k==K_SPACE) { TLocalisamfile* ditte = app()._ditte; TMask& m = f.mask(); if (m.get_bool(F_GELIDI)) { const long ditta = m.get_long(F_CODDITTA); ditte->put("CODDITTA", ditta); if (ditte->read()==NOERR) if (ditte->get("DINIZIOATT").empty()) { f.set(" "); f.error_box("La gestione della liquidazione differita richiede " "la data di inizio attivita' sull'anagrafica della ditta."); } } } return TRUE; } bool TParaliq_app::agrmin_handler(TMask_field& f, KEY k) { if (k == K_SPACE) { TLocalisamfile* attiv = app()._attiv; TMask& m = f.mask(); if (m.get_bool(F_AGRMIN)) { const long ditta = m.get_long(F_CODDITTA); attiv->put(ATT_CODDITTA, ditta); if (attiv->read(_isgteq) == NOERR && attiv->get_long(ATT_CODDITTA) == ditta && !attiv->get_bool(ATT_REGAGR)) { f.set(" "); f.error_box("La gestione degli agricoltori minimi richiede " "il settaggio del regime agricolo sull'attivita'."); } } } return TRUE; } bool TParaliq_app::credres_handler(TMask_field& f, KEY k) { if (f.to_check(k)) { const TMask& m = f.mask(); real r(f.get()); const bool euro = is_euro_value(m.get(F_CODVAL)); // Arrotondamento alle migliaia le Lire e rispetto i parametri in Euro r.round(euro ? m.get_int(F_ROUNDDIC) : -3); f.set(r.string()); } if (k == K_ENTER) // In uscita dalla maschera { const TMask& m = f.mask(); const short id = f.dlg(); const real r = m.get_real(F_CRED_RES); const int i = m.get_int(F_MESE_RES_AL); if (id == F_MESE_RES_AL && r != 0.0 && i == 0) return f.error_box("Impostare anche il mese."); if (id == F_CRED_RES && i != 0 && r == 0.0) return f.error_box("Impostare anche il credito residuo."); } return TRUE; } bool TParaliq_app::credpreccost_handler(TMask_field& f, KEY k) { if (f.to_check(k)) { const TMask& m = f.mask(); real r(f.get()); const bool euro = is_euro_value(m.get(F_CODVAL)); // Arrotondamento alle migliaia le Lire e rispetto i parametri in Euro r.round(euro ? m.get_int(F_ROUNDDIC) : -3); f.set(r.string()); } return TRUE; } bool TParaliq_app::utcred_handler(TMask_field& f, KEY k) { TMask & m = f.mask(); if ((k == K_TAB && f.focusdirty()) || !m.is_running()) { const int anno_liq = m.get_int(F_YEAR); TString80 cod_mesi; TString des_mesi(128); TString16 mese; TList_field & mese_res = ((TList_field &) m.field(F_MESE_RES_AL)); if (anno_liq >= 2000 && f.get().not_empty()) { m.field(F_CRED_PREC).set_prompt("Credito compensabile inizio anno "); m.field(F_CRED_RES).set_prompt("Credito in compensaz.utilizzato "); m.enable(F_UTCR_IVA); cod_mesi = "0|-1"; des_mesi = " |Inizio Anno"; mese = !m.field(F_CRED_RES).empty() ? "-1" : "0"; } else { m.field(F_CRED_PREC).set_prompt("Credito precedente "); m.field(F_CRED_RES).set_prompt("Credito residuo "); cod_mesi = "0|1|2|3|4|5|6|7|8|9|10|11|12"; des_mesi = " |Gennaio|Febbraio|Marzo|Aprile|Maggio|Giugno|Luglio|Agosto|Settembre|Ottobre|Novembre|Dicembre"; mese = app().rel().lfile().get("I0"); if (!m.edit_mode() || atoi(mese) < 0) mese.cut(0); } const TString16 oldmese = m.get(F_MESE_RES_AL); mese_res.replace_items(cod_mesi, des_mesi); if (m.is_running()) m.set(F_MESE_RES_AL, mese); else m.set(F_MESE_RES_AL, oldmese); } return TRUE; } void TParaliq_app::check_registers(int year) { // controlla che per ogni data attivita' esistano almeno un registro // acquisti, vendite e giornale; warning appropriato in caso negativo TSheet_field& sf = (TSheet_field&)_msk->field(F_SHEET_PLA); TTable reg("REG"); TRecfield reg_year(reg.curr(), "CODTAB", 0,3); const byte R_ACQ = 0x01; const byte R_VEN = 0x02; const byte R_ALL = R_ACQ | R_VEN; byte flags = 0x00; for (int i = 0; i < sf.items(); i++) { const TString16 att(sf.row(i).get(0)); for (reg.first(); !reg.eof(); reg.next()) { if (atoi(reg_year) != year || att != reg.get("S8")) continue; switch (reg.get_int("I0")) { case 1: // vendite flags |= R_VEN; break; case 2: // acquisti flags |= R_ACQ; break; default: break; } if (flags == R_ALL) break; } if (flags < R_ALL) { TString wrn("I seguenti registri non esistono per l'attivita' "); wrn << att << "(" << year << "):"; if ((flags & R_VEN) == 0x00) wrn << "\n\tregistro vendite"; if ((flags & R_ACQ) == 0x00) wrn << "\n\tregistro acquisti"; warning_box(wrn); } } } void TParaliq_app::init_array(TMask& m, bool update) { TSheet_field& sf = (TSheet_field&)m.field(F_SHEET_PLA); const long newditta = m.get_long(F_CODDITTA); _attiv->zero(); _attiv->put(ATT_CODDITTA, newditta); TRectype r(_attiv->curr()); int i = 0; for(_attiv->read(_isgteq); _attiv->good() && _attiv->curr() == r; _attiv->next(), i++) { TToken_string& tt = sf.row(i); // istanzia array _atts on le attivita' della ditta corrente tt = ""; tt.add(_attiv->get(ATT_CODATT)); tt.add(_attiv->get(ATT_TIPOATT)); tt.add(""); tt.add(""); tt.add(""); tt.add(""); } if (update) { sf.force_update(); TString16 freq = cache().get(LF_NDITTE,newditta).get(NDT_FREQVIVA); m.set(F_FREQ_VERS, freq); } } void TParaliq_app::on_config_change() { TConfig d(CONFIG_DITTA); _yearliq = (int)d.get_long("AnLiIv"); } bool TParaliq_app::user_create() { _rel = new TRelation(TAB_LIA); _pla = new TTable(TAB_PLA); _attiv = new TLocalisamfile(LF_ATTIV); _ditte = new TLocalisamfile(LF_NDITTE); _msk = new TMask("cg5300a"); _msk->set_handler(F_GELIDI,gelidi_handler); _msk->set_handler(F_AGRMIN,agrmin_handler); _msk->set_handler(F_CRED_RES,credres_handler); _msk->set_handler(F_CRED_PREC,credpreccost_handler); _msk->set_handler(F_CRED_COST,credpreccost_handler); _msk->set_handler(F_CODDITTA,ditta_handler); _msk->set_handler(F_UTCR_IVA,utcred_handler); ((TSheet_field&)_msk->field(F_SHEET_PLA)).set_notify(sheet_action); return TRUE; } bool TParaliq_app::user_destroy() { delete _rel; delete _attiv; delete _ditte; delete _msk; delete _pla; return TRUE; } bool TParaliq_app::sheet_action(TSheet_field& s, int r, KEY k) { // non si possono cancellare o aggiungere righe in PLA return (k != K_DEL && k != K_INS); } void TParaliq_app::init_query_mode(TMask& m) { // svuota tutto TSheet_field& sh = (TSheet_field&)m.field(F_SHEET_PLA); m.disable(DLG_DELREC); } void TParaliq_app::init_insert_mode(TMask& m) { // Inizializza array delle attivita' init_array(m, TRUE); init_modify_mode(m); if (m.get_int(F_YEAR) >= 2002) m.set(F_ROUNDLIQ, TCurrency::get_firm_dec()); } void TParaliq_app::init_modify_mode(TMask& m) { const int anno_liq = m.get_int(F_YEAR); if (anno_liq >= 2000) { m.enable(F_UTCR_IVA); } else { m.set(F_UTCR_IVA, " ", TRUE); m.disable(F_UTCR_IVA); } // Attiva la pagina degli arrotondamenti solo per le ditte in Euro dal 2002 m.enable_page(1, (anno_liq >= 2002) && (TCurrency::get_firm_dec() > 0)); } int TParaliq_app::rewrite(const TMask& m) { // scrive %LIA // scrive tutte le righe di %PLA a partire dalle righe sheet static int oldyear; TSheet_field& sf = (TSheet_field&)m.field(F_SHEET_PLA); const long firm = m.get_long(F_CODDITTA); const int year = m.get_int(F_YEAR); const char freq = m.get(F_FREQ_VERS)[0]; int err = NOERR; bool was = FALSE; for (int i = 0; err == NOERR && i < sf.items(); i++) { TToken_string& tt = sf.row(i); const TString16 att = tt.get(0); const TString16 tips = tt.get(1); TString16 codtab; codtab.format("%05ld%4d%s", firm, year, (const char*)att); _pla->zero(); _pla->put("CODTAB", codtab); _pla->remove(); // Rimuove dalla tabella PLA il record senza il tipo attivita' ad 1 (se non c'e' fa lo stesso) codtab << "1"; // Questo invece e' il codice che deve esistere realmente _pla->put("CODTAB", codtab); was =_pla->read() == NOERR; if (!was) _pla->zero(); real prorata = _pla->get_real("R8"); real es_a8 = _pla->get_real("R5"); real es_a8b = _pla->get_real("R6"); real es_a9 = _pla->get_real("R7"); _pla->put("CODTAB", codtab); // scrive i campi (vedi a read() per i nomi) // in base alla riga sheet _pla->put("S7", tips); // tipo attivita' _pla->put("R8", tt.get()); // prorata _pla->put("R5", tt.get()); // plafond art. 8 _pla->put("R6", tt.get()); // plafond art. 8bis _pla->put("R7", tt.get()); // plafond art. 9 err = (was ? _pla->rewrite() : _pla->write()); // se si e' cambiato qualcosa.. if (prorata != _pla->get_real("R8") || es_a8 != _pla->get_real("R5") || es_a8b != _pla->get_real("R6") || es_a9 != _pla->get_real("R7") || m.field(F_CRED_PREC).dirty()) { // invalida la prima liquidazione calcolata se ce n'e' TTable lim("LIM"); TRecfield lim_anno(lim.curr(),"CODTAB",0,3); TRecfield lim_mese(lim.curr(),"CODTAB",4,5); for (lim.first(); !lim.eof(); lim.next()) { if (year == atoi(lim_anno) && (freq == 'M' || (freq == 'T' && atoi(lim_mese) == 3))) { lim.put("B0",""); lim.rewrite(); break; } } } } TTable& lia = (TTable&)_rel->lfile(); lia.put("CODTAB", format("%05ld%04d", firm, year)); was = lia.read() == NOERR; if (!was) lia.zero(); m.autosave(*_rel); if (err == NOERR) err = was ? lia.rewrite() : lia.write(); if (err == NOERR && year == _yearliq) { _ditte->put(NDT_CODDITTA, firm); if (_ditte->read() == NOERR) { _ditte->put(NDT_FREQVIVA, m.get(F_FREQ_VERS)); _ditte->rewrite(); } } // per ogni anno liquidazione controlla (una volta) l'esistenza // dei registri fondamentali if (year != oldyear && err == NOERR) check_registers(year); oldyear = year; return err; } int TParaliq_app::read(TMask& m) { // legge da LIA (si istanziano i campi credito prec. e Freq. Vers // prende le attivita' una per una da _atts e // crea le righe sheet m.autoload(*get_relation()); const long firm = m.get_long(F_CODDITTA); const int year = m.get_int(F_YEAR); TSheet_field& sf = (TSheet_field&)m.field(F_SHEET_PLA); //sf.reset(); const TString16 ctab = format("%05ld%4d", firm, year); _pla->put("CODTAB", ctab); TToken_string tt(80); init_array(m, FALSE); // Carica tutti i codici attivita' for (_pla->read(_isgteq); _pla->good(); _pla->next()) { if (strncmp(ctab, _pla->get("CODTAB"), 9) == 0) { tt = _pla->get("CODTAB").mid(9,5); // codice attivita' for (int i = 0; i < sf.items(); i++) // Cerca riga corrispondente sullo sheet if (tt == sf.row(i).get(0)) break; tt.add(_pla->get("S7")); // tipo attivita' tt.add(_pla->get("R8")); // prorata tt.add(_pla->get("R5")); // plafond art. 8 tt.add(_pla->get("R6")); // plafond art. 8bis tt.add(_pla->get("R7")); // plafond art. 9 sf.row(i) = tt; } else break; } //sf.force_update(); return NOERR; } int cg5300(int argc, char* argv[]) { TParaliq_app a; a.run(argc, argv, "Parametri liquidazione"); return 0; }