// cg5300.cpp // modifica parametri contabilita' relativi alla liquidazione #include #include #include #include #include #include #include "cg5.h" #include "cg5300a.h" #include #include #define TAB_LIA "LIA" #define TAB_PLA "PLA" class CG5300_App : public TRelation_application { TRelation * _rel; TMask * _msk; TLocalisamfile * _attiv; TLocalisamfile * _ditte; int _yearliq; TTable * _pla; TArray _atts; // array di stringhe con i codici attivita' TArray _tips; // array di stringhe con i tipi attivita' long _lastditta; TString16 _freqiva; void check_registers(int year); protected: virtual bool user_create(); virtual bool user_destroy(); // minchia di cristo 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 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); void init_ditta(TMask&); // notifier static bool sheet_action(int r, KEY k); public: CG5300_App() { _lastditta = 0L;} virtual ~CG5300_App() {} }; void CG5300_App::check_registers(int year) { // controlla che per ogni data attivita' esistano almeno un registro // acquisti, vendite e giornale; warning appropriato in caso negativo 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; bool is_giornale = FALSE; byte flags = 0x00; for (int i = 0; i < _atts.items(); i++) { TString& att = (TString&)_atts[i]; for (reg.first(); !reg.eof(); reg.next()) { if (atoi(reg_year) == year && reg.get_int("I0") == 5) { is_giornale = TRUE; continue; } 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; } if (flags == R_ALL && is_giornale) 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); } } // libro giornale non si controlla per attivita' if(!is_giornale) warning_box("Non esiste probabilmente nessun " "libro giornale per l'anno %d", year); } void CG5300_App::init_ditta(TMask& m) { // qui per evitare casini da cambio ditta const long newditta = get_firm(); if (newditta != _lastditta) { _lastditta = newditta; _atts.destroy(); _attiv->zero(); _attiv->put(ATT_CODDITTA, m.get(F_CODDITTA)); TRectype r(_attiv->curr()); for(_attiv->read(_isgteq); _attiv->status() == NOERR && _attiv->curr() == r; _attiv->next()) { // istanzia array _atts on le attivita' della ditta corrente _atts.add(new TString(_attiv->get(ATT_CODATT))); _tips.add(new TString(_attiv->get(ATT_TIPOATT))); } _ditte->put(NDT_CODDITTA, _lastditta); if (_ditte->read() == NOERR) _freqiva = _ditte->get(NDT_FREQVIVA); else _freqiva = ""; } } bool CG5300_App::user_create() { TConfig d(CONFIG_DITTA); _yearliq = (int)d.get_long("AnLiIv"); _rel = new TRelation(TAB_LIA); _pla = new TTable(TAB_PLA); _attiv = new TLocalisamfile(LF_ATTIV); _ditte = new TLocalisamfile(LF_NDITTE); _msk = new TMask("cg5300a"); ((TSheet_field&)_msk->field(F_SHEET_PLA)).set_notify(sheet_action); return TRUE; } bool CG5300_App::user_destroy() { delete _rel; delete _attiv; delete _ditte; delete _msk; delete _pla; return TRUE; } bool CG5300_App::sheet_action(int r, KEY k) { // non si possono cancellare o aggiungere righe in PLA return (k != K_DEL && k != K_INS); } void CG5300_App::init_query_mode(TMask& m) { // svuota tutto TSheet_field& sh = (TSheet_field&)m.field(F_SHEET_PLA); sh.reset(); init_ditta(m); } void CG5300_App::init_insert_mode(TMask& m) { TSheet_field& sf = (TSheet_field&)m.field(F_SHEET_PLA); TToken_string tt(60); m.set(F_FREQ_VERS, _freqiva); for (int i = 0; i < _atts.items(); i++) { TString& att = (TString&)_atts[i]; TString& tips = (TString&)_tips[i]; // cerca l'attivita' in pla tt = ""; tt.add(att); tt.add(tips); tt.add(""); tt.add(""); tt.add(""); tt.add(""); sf.row(-1) = tt; } } int CG5300_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 TString16 year(m.get(F_YEAR)); int yr = atoi(year); int err = NOERR; bool was = FALSE; for (int i = 0; err == NOERR && i < _atts.items(); i++) { TToken_string& tt = sf.row(i); const TString& att = (TString&) _atts[i]; const TString16 tips(tt.get(1)); _pla->zero(); _pla->put("CODTAB", format("%s%s1", (const char *) year, (const char *) att)); 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", format("%s%s1", (const char *) year, (const char *) att)); // 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); for (lim.first(); !lim.eof(); lim.next()) { if (yr == atoi(lim_anno)) { lim.put("B0",""); lim.rewrite(); break; } } } } TTable & lia = (TTable&)_rel->lfile(); lia.zero(); lia.put("CODTAB", year); was = lia.read() == NOERR; if (!was) lia.zero(); m.autosave(); if (err == NOERR) err = (was ? lia.rewrite() : lia.write()); if (err == NOERR && year == _yearliq) { _ditte->zero(); _ditte->put(NDT_CODDITTA, _lastditta); 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 (yr != oldyear && err == NOERR) check_registers(yr); oldyear = yr; return err; } int CG5300_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(); TSheet_field& sf = (TSheet_field&)m.field(F_SHEET_PLA); TToken_string tt(60); const TString16 year(m.get(F_YEAR)); sf.reset(); for (int i = 0; i < _atts.items(); i++) { TString& att = (TString&)_atts[i]; // cerca l'attivita' in pla _pla->zero(); _pla->put("CODTAB", format("%s%s1", (const char *) year, (const char *) att)); tt = ""; tt.add(att); if (_pla->read() == NOERR) { 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 } else { tt.add(""); tt.add(""); tt.add(""); tt.add(""); tt.add(""); } sf.row(-1) = tt; } return NOERR; } int cg5300(int argc, char* argv[]) { CG5300_App a; a.run(argc, argv, "Parametri liquidazione"); return 0; }