// cg5300.cpp // modifica parametri contabilita' relativi alla liquidazione #include #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; int _yearliq; 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) { TMask& m = f.mask(); if (m.get_bool(F_GELIDI)) { const TString & cod = m.get(F_CODDITTA); const TRectype & ditta = cache().get(LF_NDITTE, cod); if (ditta.get(NDT_DINIZIOATT).empty()) { f.set(" "); f.error_box(TR("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) { TMask& m = f.mask(); if (m.get_bool(F_AGRMIN)) { const TString & cod = m.get(F_CODDITTA); const TRectype & ditta = cache().get(LF_NDITTE, cod); TString16 key; key.format("%s|%s", (const char *) cod, (const char *) ditta.get(NDT_CODATTPREV)); const TRectype & attiv = cache().get(LF_ATTIV, key); if (!attiv.get_bool(ATT_REGAGR)) { f.set(" "); f.error_box(TR("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(TR("Impostare anche il mese.")); if (id == F_CRED_RES && i != 0 && r == 0.0) return f.error_box(TR("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(TR("Credito compensabile inizio anno ")); m.field(F_CRED_RES).set_prompt(TR("Credito in compensaz.utilizzato ")); m.enable(F_UTCR_IVA); cod_mesi = "0|-1"; des_mesi = FR(" |Inizio Anno"); mese = !m.field(F_CRED_RES).empty() ? "-1" : "0"; } else { m.field(F_CRED_PREC).set_prompt(TR("Credito precedente ")); m.field(F_CRED_RES).set_prompt(TR("Credito residuo ")); cod_mesi = "0|1|2|3|4|5|6|7|8|9|10|11|12"; des_mesi = FR(" |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 = _msk->sfield(F_SHEET_PLA); const byte R_ACQ = 0x01; const byte R_VEN = 0x02; const byte R_ALL = R_ACQ | R_VEN; TRelation relreg("REG"); TRectype & reg = relreg.curr(); for (int i = 0; i < sf.items(); i++) { byte flags = 0x00; const TString16 att(sf.row(i).get(0)); TString filter; reg.put("CODTAB", year); filter.format("(S8==\"\")||(S8==\"%s\")", (const char *) att); TCursor cur(&relreg, filter, 1, ®, ®); const TRecnotype items = cur.items(); for (cur = 0L; flags != R_ALL && (cur.pos() < items); ++cur) { 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) { TString wrn(TR("I seguenti registri non esistono per l'attivita' ")); wrn << att << "(" << year << "):"; if ((flags & R_VEN) == 0x00) wrn << TR("\n\tregistro vendite"); if ((flags & R_ACQ) == 0x00) wrn << TR("\n\tregistro acquisti"); warning_box(wrn); } } } void TParaliq_app::init_array(TMask& m, bool update) { TSheet_field& sf = m.sfield(F_SHEET_PLA); const long newditta = m.get_long(F_CODDITTA); TRelation att(LF_ATTIV); TRectype & r = att.curr(); r.put(ATT_CODDITTA, newditta); TCursor cur(&att, "", 1, &r, &r); const TRecnotype items = cur.items(); int i = 0; cur.freeze(); for (cur = 0L; cur.pos() < items; ++cur, i++) { TToken_string& tt = sf.row(i); // istanzia array _atts on le attivita' della ditta corrente tt.cut(0); tt.add(r.get(ATT_CODATT)); tt.add(r.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() { open_files(LF_TABCOM, LF_TAB, LF_NDITTE, LF_ATTIV, 0); _rel = new TRelation(TAB_LIA); _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); _msk->sfield(F_SHEET_PLA).set_notify(sheet_action); return TRUE; } bool TParaliq_app::user_destroy() { delete _rel; delete _msk; 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 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 = m.sfield(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); TTable pla(TAB_PLA); 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' TRelation rellim("LIM"); TRectype & lim = rellim.curr(); lim.put("CODTAB", year); TCursor cur(&rellim, "", 1, &lim, &lim); const TRecnotype items = cur.items(); cur.freeze(); for (cur = 0L; cur.pos() < items; ++cur) { // const int mese = atoi(lim.get("CODTAB").mid(4,2)); chiedere a cinzia // if (freq == 'M' || (freq == 'T' && mese == 3)) // { rellim.lfile().reread(_lock); lim.zero("B0"); rellim.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) { TLocalisamfile ditte(LF_NDITTE); ditte.put(NDT_CODDITTA, firm); if (ditte.read(_isequal, _lock) == 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 = m.sfield(F_SHEET_PLA); TString16 ctab; TToken_string tt(80); TRelation relpla(TAB_PLA); TRectype & pla = relpla.curr(); ctab.format("%05ld%4d", firm, year); pla.put("CODTAB", ctab); TCursor cur(&relpla, "", 1, &pla, &pla); const TRecnotype items = cur.items(); int i = 0; init_array(m, FALSE); // Carica tutti i codici attivita' cur.freeze(); for (cur = 0L; cur.pos() < items; ++cur, i++) { 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; } return NOERR; } int cg5300(int argc, char* argv[]) { TParaliq_app a; a.run(argc, argv, TR("Parametri liquidazione")); return 0; }