campo-sirio/ce/ce2200.cpp

535 lines
15 KiB
C++
Raw Normal View History

#include <applicat.h>
#include <automask.h>
#include <modaut.h>
#include <progind.h>
#include <recarray.h>
#include <tabutil.h>
#include "celib.h"
#include "ce2200a.h"
#include "../cg/cglib01.h"
#include "ammce.h"
#include "catdi.h"
#include "cespi.h"
#include "salce.h"
#include "movce.h"
class TOpenesc_mask : public TAutomask
{
TDitta_cespiti& _dc;
bool _has_cg;
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
bool check_oldes();
public:
TOpenesc_mask();
};
TOpenesc_mask::TOpenesc_mask()
: TAutomask("ce2200a"), _dc(ditta_cespiti())
{
_has_cg = main_app().has_module(CGAUT);
field(F_NEWES).check_type(_has_cg ? CHECK_REQUIRED : CHECK_SEARCH);
}
// Controlla che siano stati stampati i bollati e chiuse le attivita
bool TOpenesc_mask::check_oldes()
{
bool ok = true;
const TString& oldes = get(F_OLDES);
TRelation rel("CCB");
TRectype& ccb = rel.curr();
ccb.put("CODTAB", oldes);
TCursor cur(&rel, "", 1, &ccb, &ccb);
const long items = cur.items();
cur.freeze();
TString msg;
int error = 0;
for (cur = 0L; cur.pos() < items; ++cur)
{
const bool b1 = ccb.get_bool("B1");
const bool b2 = ccb.get_bool("B2");
if (!b1 || b2)
{
if (!b1)
{
msg << TR("Non <20> stato stampato il bollato dell'attivit<69>");
error |= 0x1;
}
else
{
msg << TR("E' gi<67> stata effettuata la chiusura dell'attivit<69>");
error |= 0x2;
}
const TString8 codatt = ccb.get("CODTAB").mid(4);
msg << ' ' << oldes << ' ' << cache().get("%CAT", codatt, "S0") << ".\n";
}
}
if (error)
{
if (get_int(F_NEWES) >= _dc.esercizio_corrente())
{
if (error & 0x1)
{
msg << TR("Verra' effettuata un'apertura provvisoria.") << '\n';
set(F_PROVVIS, true);
}
msg << TR("Si desidera proseguire ugualmente?");
ok = yesno_box(msg);
}
else
ok = error_box(msg);
}
return ok;
}
bool TOpenesc_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
{
case F_OLDES:
if (e == fe_init)
{
TDate ies, fes;
const int oes = _dc.esercizio_corrente(ies, fes);
o.set(oes); set(F_OLDINIZIO, ies); set(F_OLDFINE, fes);
}
if (e == fe_init || e == fe_modify)
{
TEsercizi_contabili esc;
const int oldes = get_int(F_OLDES);
int nes = esc.next(oldes);
if (nes < 0)
nes = oldes+1;
set(F_NEWES, nes, TRUE);
if (esc.exist(nes))
{
set(F_NEWINIZIO, esc[nes].inizio());
set(F_NEWFINE, esc[nes].fine());
disable(-2);
}
else
{
TDate inizio = get_date(F_OLDFINE); ++inizio;
TDate fine = get_date(F_OLDFINE); fine.addyear(1);
set(F_NEWINIZIO, inizio);
set(F_NEWFINE, fine);
enable(-2);
}
}
if (e == fe_modify || e == fe_close)
return check_oldes();
break;
case F_NEWES:
if (e == fe_close)
{
if (o.empty())
return error_box(TR("<EFBFBD> necessario specificare il codice del nuovo esercizio"));
}
break;
default:
break;
}
return TRUE;
}
class TOpenesc : public TSkeleton_application
{
protected:
virtual bool create();
virtual void main_loop();
void incr_riv(TRectype& rec, const char* riv, const char* anni) const;
bool is_leap(int year) const;
real calc_coeff(const TDate& ies, const TDate& fes) const;
void incr_zero(TRectype& rec, const char* val, const char* valp) const;
public:
bool crea_esercizio(int oldes, int newes, const TDate& ies, const TDate& fes) const;
void crea_attivita(int oldes, int newes, bool provvis) const;
void crea_registro(int oldes, int newes) const;
void crea_categorie(int oldes, int newes) const;
void crea_saldi(int oldes, int newes) const;
void crea_ammortamenti(int oldes, int newes) const;
void test_alien(const TRectype& salce, const TDate& fines) const;
};
bool TOpenesc::create()
{
open_files(LF_TABCOM, LF_TAB, LF_CESPI, LF_AMMCE, LF_SALCE, 0);
return TSkeleton_application::create();
}
bool TOpenesc::is_leap(int year) const
{
TDate d(28,2,year);
++d;
return d.day() == 29;
}
real TOpenesc::calc_coeff(const TDate& ies, const TDate& fes) const
{
const real tot_es = fes - ies + 1;
real max_es = 365;
const int im = ies.month();
const int iy = ies.year();
const int fm = fes.month();
const int fy = fes.year();
if ((im < 3 && (fm >= 3 || fy > iy) && is_leap(iy)) ||
(fm >= 3 && (im < 3 || iy < fy) && is_leap(fy)))
max_es += 1.0;
real coeff = tot_es / max_es;
coeff.round(9);
return coeff;
}
bool TOpenesc::crea_esercizio(int oldes, int newes, const TDate& ies, const TDate& fes) const
{
// Crea l'esercizio contabile se necessario
TTable esc("ESC");
TString4 key_new;
key_new.format("%04d",newes);
esc.put("CODTAB", key_new);
if (esc.read() != NOERR)
{
if (!has_module(CGAUT))
{
esc.zero();
esc.put("CODTAB", key_new);
esc.put("D0", ies);
esc.put("D1", fes);
esc.write();
}
else
return error_box(TR("Attenzione: non esiste ancora l'esercizio contabile %04d"), newes);
}
// Crea l'esercizio cespiti se necessario
TString4 key_old;
key_old.format("%04d", oldes);
const TRectype& oldrec = cache().get("CCE", key_old);
TTable cce("CCE");
cce.put("CODTAB", key_new);
const bool found = cce.read() == NOERR;
if (!found)
{
cce.zero();
cce.put("CODTAB", key_new);
}
cce.put("S5", calc_coeff(ies, fes)); // Calcola coefficiente durata esercizio
cce.put("S6", oldrec.get("S6")); // Copia tipo arrotondamento
cce.put("I0", oldrec.get("I0")); // Copia tipo contabilit<69>
cce.put("I1", oldrec.get("I1")); // Copia tipo riproporzionamento
cce.put("I2", oldrec.get("I2")); // Copia assoggettamento art.14 C.2 legge 449/97
cce.put("I3", fes - ies + 1); // Calcola durata esercizio
cce.put("B0", oldrec.get("B0")); // Copia ditta relativa a professionista
cce.put("B3", oldrec.get("B3")); // Copia ammortamento parti vendute
cce.put("B4", oldrec.get("B4")); // Ragguaglio parti vendute
cce.put("B5", oldrec.get("B5")); // Esposizione su libro cespiti
if (found)
cce.rewrite();
else
cce.write();
return true;
}
void TOpenesc::crea_attivita(int oldes, int newes, bool provvis) const
{
TRelation rel("CCB");
TRectype& ccb = rel.curr();
ccb.put("CODTAB", oldes);
TCursor cur(&rel, "", 1, &ccb, &ccb);
const long items = cur.items();
cur.freeze();
for (cur = 0L; cur.pos() < items; ++cur)
{
if (!provvis)
{
ccb.put("B2", true); // Setta flag di chiusa
rel.rewrite();
}
// Crea nuova attivit<69>
TString16 codtab = ccb.get("CODTAB");
TString4 str; str.format("%04d", newes);
codtab.overwrite(str);
const bool leasing = ccb.get_bool("B0");
const TString8 codreg = ccb.get("S6");
ccb.zero();
ccb.put("CODTAB", codtab);
ccb.put("B0", leasing);
ccb.put("S6", codreg);
int err = rel.write();
if (err != NOERR)
rel.rewrite();
}
}
void TOpenesc::crea_registro(int oldes, int newes) const
{
TEsercizi_contabili esc;
const int old_year = esc[oldes].fine().year();
const int new_year = esc[newes].fine().year();
TRelation rel("REG");
TRectype& reg = rel.curr();
reg.put("CODTAB", old_year);
TCursor cur(&rel, "I0=7", 1, &reg, &reg);
const TRecnotype items = cur.items(); // Puo' succedere di averne pi<70> d'uno
cur.freeze();
for (cur = 0; cur.pos() < items; ++cur)
{
TString16 codtab;
codtab.format("%04d", new_year);
codtab << reg.get("CODTAB").mid(4);
reg.put("CODTAB", codtab);
// reg.zero("I1"); // Pagine stampate
rel.write();
}
}
void TOpenesc::crea_categorie(int oldes, int newes) const
{
TRelation rel(LF_CATDI);
TRectype& cat = rel.curr();
cat.put(CATDI_CODES, oldes);
TCursor cur(&rel, "", 1, &cat, &cat);
const long items = cur.items();
cur.freeze();
for (cur = 0L; cur.pos() < items; ++cur)
{
cat.put(CATDI_CODES, newes);
cat.zero(CATDI_DATE);
cat.zero(CATDI_TPOP);
int err = rel.write();
if (err != NOERR)
rel.rewrite();
}
}
void TOpenesc::incr_riv(TRectype& rec, const char* riv, const char* anni) const
{
if (rec.get_real(riv) != ZERO)
{
const int new_anni = rec.get_int(anni) + 1;
rec.put(anni, new_anni);
}
}
static bool bad_alien(const TDate& dtalien, const TDate& fines)
{
if (!dtalien.ok() || dtalien == fines)
return true;
if (dtalien < fines && dtalien.is_end_month())
return true;
return false;
}
static bool get_last_cespi(int logicnum, const char* filter, int key,
const TString& idcespite, const char* field, TString& value)
{
bool ok = false;
TRelation rel(logicnum);
TRectype& rec = rel.curr();
rec.put("IDCESPITE", idcespite);
TCursor cur(&rel, filter, key, &rec, &rec);
const TRecnotype items = cur.items();
if (items > 0)
{
cur.freeze();
cur = items-1;
value = rec.get(field);
ok = value.full();
}
return ok;
}
void TOpenesc::test_alien(const TRectype& salce, const TDate& fines) const
{
// Il cespite e' senza elementi e senza valore -> Dovrebbe risultare alienato
if (null_fields(salce, SALCE_NUMELE, SALCE_CSTO, SALCE_RIV75, SALCE_RIV83,
SALCE_RIV90, SALCE_RIV91, SALCE_RIVGF, SALCE_RIVGC))
{
const TString16 idcespite = salce.get(SALCE_IDCESPITE);
TLocalisamfile cespiti(LF_CESPI);
cespiti.put(CESPI_IDCESPITE, idcespite);
if (cespiti.read() == NOERR)
{
const TDate dtcomp = cespiti.get(CESPI_DTCOMP);
const TDate dtalien = cespiti.get(CESPI_DTALIEN);
// E' stato comprato tempo fa' ... ma ha una data di alienazione nulla o sospetta
if (dtcomp <= fines && bad_alien(dtalien, fines))
{
TDate alien2;
if (!alien2.ok())
{
// Cerca ultimo movimento di vendita/eliminazione
TString16 value;
if (get_last_cespi(LF_MOVCE, "SEGNO=\"-\"", 2,
idcespite, MOVCE_DTMOV, value))
{
const TDate dta(value);
if (dta <= fines)
alien2 = dta;
}
}
if (!alien2.ok())
{
// Cerca ultimo saldo non nullo
TString4 value;
if (get_last_cespi(LF_SALCE, "(TPSALDO=\"2\")&&(NUMELE!=\"0\")", 1,
idcespite, SALCE_CODES, value))
{
const int codes = atoi(value)+1;
TEsercizi_contabili esc;
TDate dti, dtf; esc.code2range(codes, dti, dtf);
if (dtf <= fines)
alien2 = dtf;
}
}
if (!alien2.ok())
alien2 = fines;
// Se ho trovato una data di alienazione diversa, allora la aggiorno
if (!dtalien.ok() || alien2 < dtalien)
{
cespiti.put(CESPI_DTALIEN, alien2);
cespiti.rewrite();
}
}
}
}
}
void TOpenesc::crea_saldi(int oldes, int newes) const
{
TRelation rel(LF_SALCE);
rel.add(LF_AMMCE, "CODES==CODES|IDCESPITE==IDCESPITE|TPSALDO==2|TPAMM==1");
TRectype& rec = rel.curr();
TString str;
str << '(' << SALCE_CODES << "==" << oldes << ")&&(" << SALCE_TPSALDO << "==2)";
TCursor cur(&rel, str);
const TRecnotype items = cur.items();
cur.freeze();
// Calcola data fine esercizio per eventuali alienazioni
TEsercizi_contabili esc;
const TDate fines = esc[oldes].fine();
TProgind pi(items, TR("Apertura saldi"), FALSE, TRUE);
for (cur = 0; cur.pos() < items; ++cur)
{
pi.addstatus(1);
rec.put(SALCE_CODES, newes); // Aggiorna anno di esercizio
rec.put(SALCE_TPSALDO, 1); // Aggiorna tipo saldo ad "iniziale"
incr_riv(rec, SALCE_RIV90, SALCE_ANNIPOST90); // Incrementa anni post 90
incr_riv(rec, SALCE_RIV91, SALCE_ANNIPOST91); // Incrementa anni post 91
rec.zero(SALCE_VSPMANU); // Azzera spese manutenzione
rec.zero(SALCE_DTSTBOLL); // Azzera data stampa bollato
// Incrementa gli anni di ammortamento
const TRectype& ammce = rel.curr(LF_AMMCE);
if (!null_fields(ammce, AMMCE_QNOR, AMMCE_QACC, AMMCE_QANT))
{
const int anniamm = rec.get_int(SALCE_ANNIAMM);
rec.put(SALCE_ANNIAMM, anniamm+1);
}
// Controlla se cespite alienato
test_alien(rec, fines);
const int err = rel.write();
if (err != NOERR) // Should never happen!
rel.rewrite();
}
}
void TOpenesc::incr_zero(TRectype& rec, const char* val, const char* valp) const
{
real num = rec.get_real(val);
num += rec.get_real(valp);
rec.put(val, num);
rec.zero(valp);
}
void TOpenesc::crea_ammortamenti(int oldes, int newes) const
{
TRelation rel(LF_AMMCE);
rel.add(LF_AMMCE, "IDCESPITE==IDCESPITE|CODES==CODES|TPSALDO==1|TPAMM==TPAMM", 1, 0, 883);
const TRectype& ammce1 = rel.curr(-883);
TRectype& rec = rel.curr();
TString str;
str << '(' << SALCE_CODES << "==" << oldes << ")&&(" << SALCE_TPSALDO << "==2)";
TCursor cur(&rel, str);
const long items = cur.items();
cur.freeze();
TProgind pi(items, TR("Creazione ammortamenti"), FALSE, TRUE);
for (cur = 0; cur.pos() < items; ++cur)
{
pi.addstatus(1);
rec.put(AMMCE_CODES, newes); // Aggiorna anno di esercizio
rec.put(AMMCE_TPSALDO, 1); // Aggiorna tipo saldo ad "iniziale"
rec.zero(AMMCE_CSCEN);
rec.zero(AMMCE_FZPER);
rec.zero(AMMCE_FZQUO);
// Le percentuali del nuovo esercizio devono essere uguali a quelle FINALI dell'esercizio precedente
// Purtroppo sono sempre a zero per cui prendo quelle INIZIALI
rec.put(AMMCE_PNOR, ammce1.get(AMMCE_PNOR));
rec.put(AMMCE_PACC, ammce1.get(AMMCE_PACC));
rec.put(AMMCE_PANT, ammce1.get(AMMCE_PANT));
incr_zero(rec, AMMCE_QNOR, AMMCE_QNORP);
incr_zero(rec, AMMCE_QACC, AMMCE_QACCP);
incr_zero(rec, AMMCE_QANT, AMMCE_QANTP);
incr_zero(rec, AMMCE_QPERSE, AMMCE_QPERSEP);
incr_zero(rec, AMMCE_FPRIVATO, AMMCE_FPRIVATOP);
incr_zero(rec, AMMCE_QPPRIVATE, AMMCE_QPPRIVATEP);
const int err = rel.write();
if (err != NOERR) // Should never happen!
rel.rewrite();
}
}
void TOpenesc::main_loop()
{
TOpenesc_mask m;
if (m.run() == K_ENTER)
{
const int oldes = m.get_int(F_OLDES);
const int newes = m.get_int(F_NEWES);
const TDate ies(m.get(F_NEWINIZIO));
const TDate fes(m.get(F_NEWFINE));
const bool provvis = m.get_bool(F_PROVVIS);
if (crea_esercizio(oldes, newes, ies, fes))
{
crea_attivita(oldes, newes, provvis);
crea_registro(oldes, newes);
crea_categorie(oldes, newes);
crea_saldi(oldes, newes);
crea_ammortamenti(oldes, newes);
ditta_cespiti().set_attivita(newes, 0, NULL);
}
}
}
int ce2200(int argc, char* argv[])
{
TOpenesc a;
a.run(argc, argv, TR("Apertura esercizio cespiti"));
return 0;
}