campo-sirio/cg/cg5300.cpp

463 lines
12 KiB
C++
Raw Normal View History

// cg5300.cpp
// modifica parametri contabilita' relativi alla liquidazione
#include <config.h>
#include <currency.h>
#include <msksheet.h>
#include <prefix.h>
#include <relapp.h>
#include <tabutil.h>
#include <urldefid.h>
#include <utility.h>
#include "cg5.h"
#include "cg5300a.h"
#include <attiv.h>
#include <nditte.h>
#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);
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 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:
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()));
TMask& m = f.mask();
m.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 (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))
{
real r(f.get());
TCurrency cur(r, f.mask().get(F_CODVAL));
const int ndec = cur.decimals(); // Decimali di questa valuta per gli importi
// Arrotondamento alle migliaia nel caso il numero
// di decimali della ditta sia zero (come per le lire)
// altrimenti al numero di decimali impostato
r.round(ndec == 0 ? -3 : ndec);
f.set(r.string());
}
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;
_ditte->put(NDT_CODDITTA, newditta);
if (_ditte->read() == NOERR)
freq = _ditte->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_MESE_RES_AL,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);
((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);
//sh.reset();
}
void TParaliq_app::init_insert_mode(TMask& m)
{
// Inizializza array delle attivita'
init_array(m, TRUE);
}
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(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%d", 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;
}