campo-sirio/ce/ce2101.cpp
alex d5861b30c0 Patch level : main 102
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :
Riportata la versione 1.7 aga patch 102 sul main trunk


git-svn-id: svn://10.65.10.50/trunk@9769 c028cbd2-c16b-5b4b-a496-9718f37d4682
2001-06-25 10:41:20 +00:00

1555 lines
48 KiB
C++
Executable File
Raw Blame History

#include <currency.h>
#include <recarray.h>
#include <tabutil.h>
#include <varrec.h>
#include "ce2101.h"
#include "celib.h"
#include "ammce.h"
#include "ammmv.h"
#include "cespi.h"
#include "movam.h"
#include "movce.h"
#include "salce.h"
#include "../cg/cglib01.h"
///////////////////////////////////////////////////////////
// Utility
///////////////////////////////////////////////////////////
HIDDEN void log(const char* fmt, ...)
{
/*
char msg[256];
va_list argptr;
va_start(argptr,fmt);
vsprintf(msg,fmt,argptr);
va_end(argptr);
FILE* f = fopen("trace.log", "a");
if (f != NULL)
{
fprintf(f, "%s\n", msg);
fclose(f);
}
*/
}
// Controlla se i campi sono tutti vuoti
// Cerified 99%
HIDDEN bool null_fields(const TRectype& rec, const char* fld0, const char* fld1, const char* fld2 = NULL,
const char* fld3 = NULL, const char* fld4 = NULL, const char* fld5 = NULL,
const char* fld6 = NULL, const char* fld7 = NULL, const char* fld8 = NULL)
{
if (!rec.get_real(fld0).is_zero())
return FALSE;
if (!rec.get_real(fld1).is_zero())
return FALSE;
if (fld2 && *fld2 && !rec.get_real(fld2).is_zero())
return FALSE;
if (fld3 && *fld3 && !rec.get_real(fld3).is_zero())
return FALSE;
if (fld4 && *fld4 && !rec.get_real(fld4).is_zero())
return FALSE;
if (fld5 && *fld5 && !rec.get_real(fld5).is_zero())
return FALSE;
if (fld6 && *fld6 && !rec.get_real(fld6).is_zero())
return FALSE;
if (fld7 && *fld7 && !rec.get_real(fld7).is_zero())
return FALSE;
if (fld8 && *fld8 && !rec.get_real(fld8).is_zero())
return FALSE;
return TRUE;
}
// Azzera i campi fld del record rec
// Cerified 99%
HIDDEN void zero_fields(TRectype& rec, const char* fld0, const char* fld1, const char* fld2 = NULL,
const char* fld3 = NULL, const char* fld4 = NULL, const char* fld5 = NULL,
const char* fld6 = NULL, const char* fld7 = NULL, const char* fld8 = NULL,
const char* fld9 = NULL, const char* fld10 = NULL, const char* fld11 = NULL)
{
rec.zero(fld0);
rec.zero(fld1);
if (fld2 && *fld2) rec.zero(fld2);
if (fld3 && *fld3) rec.zero(fld3);
if (fld4 && *fld4) rec.zero(fld4);
if (fld5 && *fld5) rec.zero(fld5);
if (fld6 && *fld6) rec.zero(fld6);
if (fld7 && *fld7) rec.zero(fld7);
if (fld8 && *fld8) rec.zero(fld8);
if (fld9 && *fld9) rec.zero(fld9);
if (fld10 && *fld10) rec.zero(fld10);
if (fld11 && *fld11) rec.zero(fld11);
}
///////////////////////////////////////////////////////////
// TCespite
///////////////////////////////////////////////////////////
// Limite massimo per ammortamento "immediato"
// Certified 99%
real TCespite::un_milione() const
{
static real million;
if (million.is_zero())
{
million = 1000000.0;
if (TCurrency::get_firm_dec() == 2)
{
million /= 1936.27;
million.round(2);
}
}
return million;
}
// Riempie la chiave principale di un record di SALCE
// Certified 100%
void TCespite::fill_sal_key(TRectype& salce, int esercizio, int tpsal) const
{
salce.zero();
salce.put(SALCE_IDCESPITE, get(CESPI_IDCESPITE));
salce.put(SALCE_CODES, esercizio);
salce.put(SALCE_TPSALDO, tpsal);
}
// Riempie la chiave principale di un record di AMMCE
// Certified 100%
void TCespite::fill_amm_key(TRectype& ammce, int esercizio, int tpsal, int tpamm) const
{
ammce.zero();
ammce.put(AMMCE_IDCESPITE, get(CESPI_IDCESPITE));
ammce.put(AMMCE_CODES, esercizio);
ammce.put(AMMCE_TPSALDO, tpsal);
ammce.put(AMMCE_TPAMM, tpamm);
}
// Lettura ed eventuale creazione dei saldi iniziali e progressivi
// Certified 99%
void TCespite::read_sal(int esercizio)
{
TLocalisamfile salce(LF_SALCE);
fill_sal_key(salce.curr(), esercizio, 1);
if (salce.read() == NOERR)
_salini = salce.curr();
else
{
fill_sal_key(_salini, esercizio, 1);
_salini.write(salce);
}
_salpro = _salini;
_salpro.put(SALCE_TPSALDO, 2);
}
// Lettura ed eventuale creazione degli ammortamenti iniziali e progressivi
// Certified 99%
void TCespite::read_amm(int esercizio, int tipo)
{
TLocalisamfile ammce(LF_AMMCE);
fill_amm_key(ammce.curr(), esercizio, 1, tipo);
if (ammce.read() == NOERR)
_ammini = ammce.curr();
else
{
fill_amm_key(_ammini, esercizio, 1, tipo);
_ammini.write(ammce);
}
fill_amm_key(ammce.curr(), esercizio, 2, tipo);
if (ammce.read() == NOERR)
_ammpro = ammce.curr();
else
{
fill_amm_key(_ammpro, esercizio, 2, tipo);
_ammpro.write(ammce);
}
_ammpro.put(AMMCE_QNORP, _ammini.get(AMMCE_QNOR));
_ammpro.put(AMMCE_QACCP, _ammini.get(AMMCE_QACC));
_ammpro.put(AMMCE_QANTP, _ammini.get(AMMCE_QANT));
_ammpro.put(AMMCE_QPERSEP, _ammini.get(AMMCE_QPERSE));
_ammpro.put(AMMCE_FPRIVATOP, _ammini.get(AMMCE_FPRIVATO));
_ammpro.put(AMMCE_QPPRIVATEP, _ammini.get(AMMCE_QPPRIVATE));
_ammpro.put(AMMCE_SCELTE, _ammini.get(AMMCE_SCELTE));
zero_fields(_ammpro, AMMCE_MSG01, AMMCE_MSG02, AMMCE_MSG03, AMMCE_MSG04,
AMMCE_MSG05, AMMCE_MSGD05, AMMCE_MSG06, NULL);
const real cde = ditta_cespiti().coefficiente_durata_esercizio();
if (cde != 1.0)
_ammpro.put(AMMCE_MSG02, "X");
const int uso_promiscuo = get_int(CESPI_USOPROM);
if (uso_promiscuo > 1)
_ammpro.put(AMMCE_MSG03, "X");
}
// Salva SALPRO
// Certified 100%
void TCespite::save_sal() const
{
TLocalisamfile salce(LF_SALCE);
if (_salpro.rewrite(salce) != NOERR)
_salpro.write(salce);
}
// Salva AMMPRO
// Certified 100%
void TCespite::save_amm() const
{
TLocalisamfile ammce(LF_AMMCE);
if (_ammpro.rewrite(ammce) != NOERR)
_ammpro.write(ammce);
}
// Ritorna il record della categoria del cespite
// Certified 100%
const TRectype& TCespite::categoria() const
{
const int gruppo = get_int(CESPI_CODCGRA);
const TString4 specie = get(CESPI_CODSPA);
const int categ = get_int(CESPI_CODCAT);
return ditta_cespiti().categoria(gruppo, specie, categ);
}
// Tipo del cespite: 0 = Materiale, 1 = Immateriale, 2 = Pluriennale
// Attenzione: analisi, foxpro, neurocampo
// Codifica: M I P 1 2 3 0 1 2
// Certified 100%
TTipo_cespite TCespite::tipo() const
{
const int tc = categoria().get_int("I0");
return tc==0 ? tc_materiale : (tc==1 ? tc_immateriale : tc_pluriennale);
}
// Registra un messaggio 5 su AMMPRO
// Certified 100%
void TCespite::set_msg05(const char* msg)
{
_ammpro.put("MSG05", "X");
_ammpro.put("MSGD05", msg);
save_amm();
}
// Controlla se un cespite <20> valido, nel senso che si puo' calcolarne l'ammortamento
// Certified 75%
bool TCespite::valido(int tipo_sit)
{
log("- Controllo validita`");
const TDitta_cespiti& dc = ditta_cespiti();
TDate ini_es, fin_es;
const int esercizio = dc.esercizio_corrente(ini_es, fin_es);
// Legge ammpro per scriverci eventuali messaggi
read_amm(esercizio, tipo_sit);
// Cespite alienato
const TDate alienazione = get(CESPI_DTALIEN);
if (alienazione.ok() && alienazione < ini_es)
{
set_msg05("cespite completamente eliminato.");
return FALSE;
}
// Categoria non ammortizzabile
const TRectype& cat = categoria();
if (cat.get_bool("B0"))
{
set_msg05("categoria non ammortizzabile.");
return FALSE;
}
// Cespite non ancora completato
const TDate completamento = get(CESPI_DTCOMP);
if (!completamento.ok() || completamento > fin_es)
{
set_msg05("cespite non completato.");
return FALSE;
}
// Cespite materiale non in funzione
// Immateriali, no tuir, non in funzione
const TTipo_cespite tc = tipo();
if (tc == tc_materiale || (tc == tc_immateriale && !get_bool(CESPI_TUIR)))
{
const TDate funzione = get(CESPI_DTFUNZ);
if (!funzione.ok() || funzione > fin_es)
{
set_msg05("cespite non ancora entrato in funzione.");
return FALSE;
}
}
// Materiali no TUIR, non conseguiti ricavi
// Pluriennali, non conseguiti ricavi
if ((tc == tc_materiale && !get_bool(CESPI_TUIR)) || tc == tc_pluriennale)
{
if (dc.rinvio_ammortamento_ai_primi_ricavi())
{
const TDate& ricavi = dc.data_primi_ricavi();
if (!ricavi.ok() || ricavi > fin_es)
{
set_msg05("non sono ancora stati conseguiti ricavi.");
return FALSE;
}
}
}
// Pluriennali nuovi, decorrenza ammortamento anno successivo
if (tc == tc_pluriennale && cat.get_bool("B1"))
{
if (completamento >= ini_es && completamento <= fin_es)
{
set_msg05("decorrenza ammortamenti dall'esercizio successivo.");
return FALSE;
}
}
return TRUE;
}
// Calcola il valore ammortizzabile di un cespite in base a quanto scritto in SALPRO
// Certified 50%
real TCespite::val_amm(int tipo_sit) const
{
real val = _salpro.get_real(SALCE_CSTO) - _salpro.get_real(SALCE_PLUSREIN) +
_salpro.get_real(SALCE_RIV75) + _salpro.get_real(SALCE_RIV83);
if (tipo_sit == 1 || get_bool(CESPI_LEASING))
{
val -= _salpro.get_real(SALCE_VNONAMM);
val += _salpro.get_real(SALCE_RIVGF);
}
else
{
val += _salpro.get_real(SALCE_RIVGC);
}
const real riv90 = _salpro.get(SALCE_RIV90);
const real riv91 = _salpro.get(SALCE_RIV91);
if (riv90 != ZERO || riv91 != ZERO)
{
const int annipost90 = _salpro.get_int(SALCE_ANNIPOST90);
if (riv91 != ZERO || annipost90 >= 3)
val += riv90;
}
val += riv91;
return val;
}
// Calcola il residuo ammortizzabile di un cespite in base a quanto scritto in SALPRO e AMMPRO
// Certified 75%
real TCespite::res_amm(int tipo_sit) const
{
const real valamm = val_amm(tipo_sit); // Valore ammortizzabile
real fondo; // Fondo ammortamento
fondo += _ammpro.get_real(AMMCE_QNORP);
fondo += _ammpro.get_real(AMMCE_QANTP);
fondo += _ammpro.get_real(AMMCE_QACCP);
fondo += _ammpro.get_real(AMMCE_QPERSEP);
fondo += _ammpro.get_real(AMMCE_QPPRIVATEP);
fondo += _ammpro.get_real(AMMCE_FPRIVATOP);
const real resamm = valamm - fondo; // Residuo da ammortizzare
return resamm;
}
// Cerca nella tabella dei limiti l'ultima data precedente alla fine esercizio passata come parametro
// Certified 90%
TRectype& date2limit(const TDate& d)
{
static TAssoc_array limits;
// const TString16 key = d.string(ANSI); // Non serve l'intera data: tabella del c....
TString16 key; key.format("%04d", d.year());
TRectype* lim = (TRectype*)limits.objptr(key);
if (lim == NULL)
{
TTable clm("%CLM");
bool ok = clm.last() == NOERR;
if (ok)
{
TDate datalim = clm.get("CODTAB");
ok = d >= datalim;
while (!ok)
{
if (clm.prev() != NOERR)
break;
datalim = clm.get("CODTAB");
ok = d >= datalim;
}
}
lim = new TRectype(clm.curr());
if (!ok) // Should never happen!
lim->zero();
limits.add(key, lim);
}
return *lim;
}
// Calcola il limite massimo ammortizzabile per il tipo di veicolo
// Certified 90%
real TCespite::get_limit() const
{
real limite = -1.0; // Partiamo con limite non valido che in realt<6C> e' considerato +infinito
const int tipo_veicolo = get_int(CESPI_FLGTPVEI);
// Mi pare inutile cercare limiti se <20> un veicolo senza limiti!
if (tipo_veicolo > 1 && tipo_veicolo < 5)
{
TDate inies, fines;
ditta_cespiti().esercizio_corrente(inies, fines);
const TRectype& clm = date2limit(fines);
// Questo if contiene la funzione fox cerca_limite
// Stabilisce il limite in base al tipo di veicolo ed al suo uso
if (!clm.empty())
{
switch(tipo_veicolo)
{
case 2: // Autoveicolo
{
const int uso_promiscuo = get_int(CESPI_USOPROM);
if (uso_promiscuo == 2 || uso_promiscuo == 4)
limite = clm.get_real("R0"); else
if (uso_promiscuo == 3 || uso_promiscuo == 5)
limite = clm.get_real("R1");
}
break;
case 3: limite = clm.get_real("R2"); break; // Motociclo
case 4: limite = clm.get_real("R3"); break; // Ciclomotore
default: break;
}
}
}
return limite;
}
// Calcola spese manutenzione da scrivere su SALPRO
// Certified 75%
real TCespite::calcola_spese_manutenzione(const real& valamm)
{
const TDitta_cespiti& cce = ditta_cespiti();
real vspmanu = valamm;
if (!cce.esercizio_costituzione())
{
const real coeff = cce.coefficiente_durata_esercizio();
real limite = get_limit();
if (vspmanu < limite || limite < ZERO)
limite = vspmanu;
vspmanu = coeff * limite;
}
const int usoprom = get_int(CESPI_USOPROM);
if (usoprom == 2 || usoprom == 4)
vspmanu = vspmanu * 0.50; else // 50%
if (usoprom == 3 || usoprom == 5)
vspmanu = vspmanu * 0.80; // 80%
return vspmanu;
}
void TCespite::prepara_saldi(int tipo_sit, bool is_valid)
{
log("- Preparazione saldi tipo %d", tipo_sit);
const TDitta_cespiti& cce = ditta_cespiti();
TDate inies, fines;
const int esercizio = cce.esercizio_corrente(inies, fines);
read_sal(esercizio);
if (is_valid)
{
const int tpspeman = get_int(CESPI_TPSPEMAN);
if ((tpspeman == 2 || tpspeman == 3) && inies.year() > cce.anno_tuir())
{
const real valamm = val_amm(tipo_sit);
real vspmanu = calcola_spese_manutenzione(valamm); // Non arrotondare qui! Altrove serve cos<6F> com'<27>
cce.arrotonda(vspmanu);
_salpro.put(SALCE_VSPMANU, vspmanu);
}
}
else
{
_salpro.zero(SALCE_VSPMANU);
}
save_sal();
}
// Incrementa il campo fdst del record dst col campo fsrc del record src in base al segno specificato
// Certified 100%
void TCespite::incr_field(TRectype& dst, const char* fdst, const TRectype& src, const char* fsrc, char segno) const
{
const real num = src.get(fsrc);
if (!num.is_zero())
{
real val = dst.get(fdst);
if (segno == '-')
val -= num;
else
val += num;
dst.put(fdst, val);
}
}
// Applica tutte le rettifice al movimento tmv
// Certified 10%
void TCespite::applica_rettifiche(TRectype& tmv, TRectype& tmvam, int tipo_sit)
{
TRelation rel(LF_MOVCE);
TString expr; expr << "IDCESPITE==IDCESPITE|IDMOV==IDMOV|TPAMM==\"" << tipo_sit << '"';
rel.add(LF_MOVAM, expr);
const TString16 id = get(CESPI_IDCESPITE);
// Il cursore delle rettifiche usa la chiave 2: IDCESPITE+IDMOV
// Per cui parto a selezionare le possibili rettifiche dal movimento da rettificare ...
TRectype fromret(LF_MOVCE);
fromret.put(MOVCE_IDCESPITE, id);
fromret.put(MOVCE_IDMOV, tmv.get(MOVCE_IDMOV));
// ... in poi
TRectype toret(LF_MOVCE);
toret.put(MOVCE_IDCESPITE, id);
TString filtro;
filtro << MOVCE_IDRET << "==" << tmv.get(MOVCE_IDMOV); // Confronto numerico!
TCursor movcur(&rel, filtro, 2, &fromret, &toret);
const long items = movcur.items();
if (items > 0) // Se ci sono rettifiche
{
log("- Applicazione %ld rettifiche al movimento %s", items, (const char*)tmv.get(MOVCE_IDMOV));
movcur.freeze();
for (movcur = 0L; movcur.pos() < items; ++movcur)
{
TRectype& movret = rel.curr();
const char segno = movret.get_char(MOVCE_SEGNO);
incr_field(tmv, MOVCE_NUMELE, movret, MOVCE_NUMELE, segno);
incr_field(tmv, MOVCE_CSTO, movret, MOVCE_CSTO, segno);
incr_field(tmv, MOVCE_VNONAMM, movret, MOVCE_VNONAMM, segno);
incr_field(tmv, MOVCE_PLUSREIN, movret, MOVCE_PLUSREIN, segno);
incr_field(tmv, MOVCE_RIV75, movret, MOVCE_RIV75, segno);
incr_field(tmv, MOVCE_RIV83, movret, MOVCE_RIV83, segno);
incr_field(tmv, MOVCE_RIV90, movret, MOVCE_RIV90, segno);
incr_field(tmv, MOVCE_RIV91, movret, MOVCE_RIV91, segno);
incr_field(tmv, MOVCE_RIVGF, movret, MOVCE_RIVGF, segno);
incr_field(tmv, MOVCE_RIVGC, movret, MOVCE_RIVGC, segno);
incr_field(tmv, MOVCE_IMPVEN, movret, MOVCE_IMPVEN, segno);
if (rel.is_first_match(LF_MOVAM))
{
const TRectype& ammret = rel.curr(LF_MOVAM);
incr_field(tmvam, MOVAM_QNOR, ammret, MOVAM_QNOR, segno);
incr_field(tmvam, MOVAM_QANT, ammret, MOVAM_QANT, segno);
incr_field(tmvam, MOVAM_QACC, ammret, MOVAM_QACC, segno);
incr_field(tmvam, MOVAM_QPERSE, ammret, MOVAM_QPERSE, segno);
incr_field(tmvam, MOVAM_FPRIVATO, ammret, MOVAM_FPRIVATO, segno);
incr_field(tmvam, MOVAM_QPPRIVATE, ammret, MOVAM_QPPRIVATE, segno);
}
}
}
}
void TCespite::aggiorna_salpro(const TRectype& tmv, const TRectype& tmvam, char segno)
{
log("= Aggiornamento saldi ed ammortamenti progressivi");
incr_field(_salpro, SALCE_NUMELE, tmv, MOVCE_NUMELE, segno);
incr_field(_salpro, SALCE_CSTO, tmv, MOVCE_CSTO, segno);
incr_field(_salpro, SALCE_VNONAMM, tmv, MOVCE_VNONAMM, segno);
incr_field(_salpro, SALCE_PLUSREIN, tmv, MOVCE_PLUSREIN, segno);
incr_field(_salpro, SALCE_RIV75, tmv, MOVCE_RIV75, segno);
incr_field(_salpro, SALCE_RIV83, tmv, MOVCE_RIV83, segno);
incr_field(_salpro, SALCE_RIV90, tmv, MOVCE_RIV90, segno);
incr_field(_salpro, SALCE_RIV91, tmv, MOVCE_RIV91, segno);
incr_field(_salpro, SALCE_RIVGF, tmv, MOVCE_RIVGF, segno);
incr_field(_salpro, SALCE_RIVGC, tmv, MOVCE_RIVGC, segno);
incr_field(_salpro, SALCE_VSPMANU, tmv, "VSPMANU", segno); // Campo virtuale su tmv!
save_sal();
incr_field(_ammpro, AMMCE_QNORP, tmvam, MOVAM_QNOR, segno);
incr_field(_ammpro, AMMCE_QACCP, tmvam, MOVAM_QACC, segno);
incr_field(_ammpro, AMMCE_QANTP, tmvam, MOVAM_QANT, segno);
incr_field(_ammpro, AMMCE_QPERSEP, tmvam, MOVAM_QPERSE, segno);
incr_field(_ammpro, AMMCE_FPRIVATOP, tmvam, MOVAM_FPRIVATO, segno);
incr_field(_ammpro, AMMCE_QPPRIVATEP, tmvam, MOVAM_QPPRIVATE, segno);
save_amm();
}
// Calcola il valore ammortizzabile del movimento tmv
// Certified 50%
real TCespite::mov_val_amm(const TRectype& tmv) const
{
const real riv90 = tmv.get_real(MOVCE_RIV90);
const real riv91 = tmv.get_real(MOVCE_RIV91);
real val = tmv.get_real(MOVCE_CSTO) - tmv.get_real(MOVCE_VNONAMM) + tmv.get_real(MOVCE_RIV75) +
tmv.get_real(MOVCE_RIV83) + riv90 + riv91 + tmv.get_real(MOVCE_RIVGF);
const int anni_post90 = _salini.get_int(SALCE_ANNIPOST90);
const int anni_post91 = _salini.get_int(SALCE_ANNIPOST91);
if (riv91 == ZERO)
{
if (anni_post90 < 3)
val -= riv90;
}
else
{
if (anni_post91 == 0)
val -= riv90;
}
if (anni_post91 == 0)
val -= riv91;
return val;
}
// Calcola il residuo da ammortizzare del movimento tmv
// Certified 50%
real TCespite::mov_res_amm(const TRectype& tmv, const TRectype& tmvam) const
{
real resamm = mov_val_amm(tmv);
resamm -= tmvam.get_real(MOVAM_QNOR);
resamm -= tmvam.get_real(MOVAM_QANT);
resamm -= tmvam.get_real(MOVAM_QACC);
return resamm;
}
// Funzione chiamata da rip_elem e rip_costo
// Cerified 90%
void TCespite::rip_jolly(TRelation& rel, TRectype& tmv, TRectype& tmvam, const real& num, const real& den)
{
TDitta_cespiti& cce = ditta_cespiti();
TRectype& movsem = rel.curr(LF_MOVCE);
TRectype& movam = rel.curr(LF_MOVAM);
int i;
const char* flm[] = { MOVCE_CSTO, MOVCE_VNONAMM, MOVCE_PLUSREIN, MOVCE_RIV75, MOVCE_RIV83,
MOVCE_RIV90, MOVCE_RIV91, MOVCE_RIVGF, MOVCE_RIVGC, NULL };
for (i = 0; flm[i]; i++)
{
real n = _salpro.get_real(flm[i]) * num / den;
cce.arrotonda(n);
tmv.put(flm[i], n);
movsem.put(flm[i], n);
}
rel.lfile(LF_MOVCE).rewrite();
const char* fla[] = { MOVAM_QNOR, MOVAM_QANT, MOVAM_QACC, MOVAM_QPERSE,
MOVAM_FPRIVATO, MOVAM_QPPRIVATE, NULL };
TString16 afl;
for (i = 0; fla[i]; i++)
{
afl = fla[i]; afl << "P";
real n = _ammpro.get_real(afl) * num / den;
cce.arrotonda(n);
tmvam.put(fla[i], n);
movam.put(fla[i], n);
}
rel.lfile(LF_MOVAM).rewrite();
}
// Riproporzionare importi a partire dal numero di elementi
// Certified 100%
void TCespite::rip_elem(TRelation& rel, TRectype& tmv, TRectype& tmvam)
{
bool ok = null_fields(tmv, MOVCE_VNONAMM, MOVCE_PLUSREIN, MOVCE_RIV75,
MOVCE_RIV83, MOVCE_RIV90, MOVCE_RIV91, MOVCE_RIVGF, MOVCE_RIVGC);
if (ok)
{
log("# Ripartizionamento importi in base agli elementi");
const real num = tmv.get(MOVCE_NUMELE);
const real den = _salpro.get(SALCE_NUMELE);
if (den > ZERO)
rip_jolly(rel, tmv, tmvam, num, den);
else
log("! - Numero elementi non valido: %s", den.string());
}
}
// Riproporzionare importi a partire dal costo storico
// Certified 100%
void TCespite::rip_costo(TRelation& rel, TRectype& tmv, TRectype& tmvam)
{
log("# Ripartizionamento importi in base al costo storico");
const real num = tmv.get(MOVCE_CSTO);
const real den = _salpro.get(SALCE_CSTO);
if (den > ZERO)
rip_jolly(rel, tmv, tmvam, num, den);
else
log("! - Costo non valido: %s", den.string());
}
// Calcola una quota di ammortamento: semplicemente moltiplica il valore ammortizzabile per una
// percentuale ed ottiene la quota. Se questa supera il residuo da ammortizzare allora
// pone la quota uguale al residuo e ricalcola la percentuale effettiva
real TCespite::calc_quota(const real& valamm, const real& perric,
const real& residuo, real& pereff, TRelation* mov /* =NULL */)
{
real quota;
// Caso anomalo di percentuale nulla
if (perric <= ZERO || valamm <= ZERO)
{
pereff = ZERO;
return quota;
}
// Caso normale
quota = valamm * perric / 100.0;
pereff = perric;
const TDitta_cespiti& cce = ditta_cespiti();
if (mov != NULL && cce.ragguaglio_ammortamenti_parti_vendute())
{
TRectype& ammmv = mov->curr(LF_AMMMV);
TString note;
if (!ammmv.get_bool(AMMMV_FZQUO) && !ammmv.get_bool(AMMMV_FZPER))
{
TDate inies, fines;
cce.esercizio_corrente(inies, fines);
const TDate dtmov = mov->curr(LF_MOVCE).get(MOVCE_DTMOV);
const TDate dtcomp = get(CESPI_DTCOMP);
const long giorni_possesso = dtmov - fnc_max(inies, dtcomp) + 1;
const long giorni_esercizio = fines - inies + 1;
quota = quota * giorni_possesso / giorni_esercizio;
note << "Ammortamenti ragguagliati a "
<< giorni_possesso << " giorni di possesso su "
<< giorni_esercizio << " giorni dell'esercizio";
}
ammmv.put(AMMMV_NOTE, note);
}
const real coeff_durata = cce.coefficiente_durata_esercizio();
quota *= coeff_durata;
cce.arrotonda(quota);
if (quota > residuo)
{
quota = residuo;
if (valamm > ZERO)
pereff = (quota * 100.0) / (coeff_durata * valamm);
else
pereff = ZERO;
}
return quota;
}
// Calcolo delle quote perse
// Certified 50%
real TCespite::calc_quote_perse(const real& valamm, const real& peric, const real& residuo,
const real& quotamm, bool mov_vend, const TDate& dtmov)
{
const TDitta_cespiti& cce = ditta_cespiti();
const real coeff_durata = cce.coefficiente_durata_esercizio();
real quota = valamm * peric / 100.0 * coeff_durata;
if (mov_vend)
{
TDate inies, fines;
cce.esercizio_corrente(inies, fines);
const TDate dtcomp = get(CESPI_DTCOMP);
const real giorni_possesso = dtmov - fnc_max(inies, dtcomp) + 1;
const real giorni_esercizio = fines - inies + 1;
quota = quota * giorni_possesso / giorni_esercizio;
}
cce.arrotonda(quota);
if (quota < residuo)
{
const bool amm_rit = _ammini.get_bool(AMMCE_AMMRIT);
if (quota > quotamm && !amm_rit)
quota -= quotamm;
else
quota = ZERO;
}
else
quota = ZERO;
return quota;
}
void TCespite::agg_quota(int tipo_sit, const real& movvalamm, TRectype& rec, const char* field, bool calcq)
{
const int tipo_veicolo = get_int(CESPI_FLGTPVEI);
const int uso_promiscuo = get_int(CESPI_USOPROM);
real perc;
switch (uso_promiscuo)
{
case 2:
case 4: perc = 0.5; break;
case 3:
case 5: perc = 0.8; break;
default: break;
}
if (perc > ZERO)
{
const real mva = (rec.num() == LF_AMMMV) ? movvalamm : val_amm(tipo_sit);
real clim;
if (tipo_veicolo >= 2 && tipo_veicolo <= 4)
{
clim = get_limit();
if (clim < ZERO || mva < clim)
clim = mva;
}
else
clim = mva;
const TDitta_cespiti& cce = ditta_cespiti();
const real quotat = rec.get(field);
const real limcsto = clim / mva;
real campo = quotat * limcsto * perc;
cce.arrotonda(campo);
rec.put(field, campo);
if (strcmp(field, "QNOR") == 0)
rec.put("FPRIVATO", quotat - campo);
else
rec.put("FPRIVATO", rec.get_real("FPRIVATO") + quotat - campo);
if (calcq)
{
const real quotap = rec.get("QPERSE");
real qp = quotap * limcsto * perc;
cce.arrotonda(qp);
rec.put("QPERSE", qp);
rec.put("QPPRIVATE", quotap - qp);
}
}
}
void TCespite::calc_perc(TRelation& rel, const TRectype& tmv, const TRectype& tmvam, int tipo_sit)
{
const TDitta_cespiti& cce = ditta_cespiti();
const real coeff = cce.coefficiente_durata_esercizio();
TRectype& ammmv = rel.curr(LF_AMMMV);
ammmv.put(AMMMV_PNOR, _ammini.get(AMMCE_PNOR));
ammmv.put(AMMMV_PANT, _ammini.get(AMMCE_PANT));
ammmv.put(AMMMV_PACC, _ammini.get(AMMCE_PACC));
if (ammmv.get_bool(AMMMV_FZQUO))
{
real resamm = mov_res_amm(tmv, tmvam);
if (resamm > ZERO)
{
if (resamm < ammmv.get_real(AMMMV_QNOR))
{
ammmv.put(AMMMV_QNOR, resamm);
const real penor = resamm / coeff * 100.0 / mov_val_amm(tmv);
ammmv.put(AMMMV_PENOR, penor);
}
resamm -= ammmv.get_real(AMMMV_QNOR) + ammmv.get_real(AMMMV_FPRIVATO);
if (resamm > ZERO)
{
if (resamm < ammmv.get_real(AMMMV_QACC))
{
ammmv.put(AMMMV_QACC, resamm);
const real peacc = resamm / coeff * 100.0 / mov_val_amm(tmv);
ammmv.put(AMMMV_PEACC, peacc);
}
resamm -= ammmv.get_real(AMMMV_QACC);
}
else
zero_fields(ammmv, AMMMV_QANT, AMMMV_PEANT, AMMMV_QACC, AMMMV_PEACC, NULL);
// Controllo se residuo a zero per finire
if (resamm > ZERO)
{
// Controllo se forzato anche quota anticipato
if (resamm < ammmv.get_real(AMMMV_QANT))
{
ammmv.put(AMMMV_QANT, resamm);
const real peant = resamm / coeff * 100.0 / mov_val_amm(tmv);
ammmv.put(AMMMV_PEANT, peant);
}
}
else
{
ammmv.zero(AMMMV_QANT); ammmv.zero(AMMMV_PEANT);
}
}
else
{
zero_fields(ammmv, AMMMV_QNOR, AMMMV_PENOR, AMMMV_QANT, AMMMV_PEANT, AMMMV_QACC, AMMMV_PEACC, NULL);
}
} else
if (ammmv.get_bool(AMMMV_FZPER))
{
ammmv.put(AMMMV_PENOR, ammmv.get(AMMMV_PNOR));
ammmv.put(AMMMV_PEANT, ammmv.get(AMMMV_PANT));
ammmv.put(AMMMV_PEACC, ammmv.get(AMMMV_PACC));
real resamm = mov_res_amm(tmv, tmvam);
if (resamm > ZERO)
{
const real penor = ammmv.get(AMMMV_PENOR);
real per_eff;
const real qnor = calc_quota(mov_val_amm(tmv), penor, resamm, per_eff, &rel);
ammmv.put(AMMMV_QNOR, qnor);
ammmv.put(AMMMV_PNOR, per_eff);
resamm -= qnor + ammmv.get_real(AMMMV_FPRIVATO);
const real peacc = ammmv.get(AMMMV_PEACC);
if (resamm > ZERO && peacc > ZERO)
{
const real qacc = calc_quota(mov_val_amm(tmv), peacc, resamm, per_eff, &rel);
ammmv.put(AMMMV_QACC, qacc);
ammmv.put(AMMMV_PACC, per_eff);
resamm -= qacc;
}
const real peant = ammmv.get(AMMMV_PEANT);
if (resamm > ZERO && peant > ZERO)
{
const real qant = calc_quota(mov_val_amm(tmv), peant, resamm, per_eff, &rel);
ammmv.put(AMMMV_QANT, qant);
ammmv.put(AMMMV_PANT, per_eff);
}
}
else
{
zero_fields(ammmv, AMMMV_QNOR, AMMMV_PENOR, AMMMV_QANT, AMMMV_PEANT, AMMMV_QACC, AMMMV_PEACC, NULL);
}
}
else
{
ammmv.put(AMMMV_PENOR, ammmv.get(AMMMV_PNOR));
ammmv.put(AMMMV_PEANT, ammmv.get(AMMMV_PANT));
ammmv.put(AMMMV_PEACC, ammmv.get(AMMMV_PACC));
if (_salini.get_int(SALCE_ANNIAMM) == 0 && tipo() == tc_materiale && !cce.professionista())
{
const real numele = _salpro.get_real(SALCE_NUMELE)+tmv.get_real(MOVCE_NUMELE);
const real mva = mov_val_amm(tmv) / numele;
if (_ammini.get_bool(AMMCE_CSCEN) && mva < un_milione())
{
ammmv.put(AMMMV_PENOR, "100");
ammmv.zero(AMMMV_PEANT);
ammmv.zero(AMMMV_PEACC);
}
else
{
ammmv.put(AMMMV_PENOR, ammmv.get_real(AMMMV_PNOR)/2.0);
ammmv.put(AMMMV_PEANT, ammmv.get_real(AMMMV_PANT)/2.0);
ammmv.put(AMMMV_PEACC, ammmv.get_real(AMMMV_PACC)/2.0);
}
}
real resamm = mov_res_amm(tmv, tmvam);
if (resamm > ZERO)
{
// Calcolare quota ammortamento normale
const real valamm = mov_val_amm(tmv);
const real penor = ammmv.get_real(AMMMV_PENOR);
real per_eff;
const real qnor = calc_quota(valamm, penor, resamm, per_eff, &rel);
ammmv.put(AMMMV_QNOR, qnor);
ammmv.put(AMMMV_PENOR, per_eff);
// Calcolare quote perse
const TDate dtmov = tmv.get(MOVCE_DTMOV);
const real quote_perse = calc_quote_perse(valamm, per_eff, resamm, qnor, TRUE, dtmov);
ammmv.put(AMMMV_QPERSE, quote_perse);
if (tipo_sit == 1 && get_int(CESPI_USOPROM) > 1)
agg_quota(tipo_sit, valamm, ammmv, "QNOR", TRUE);
else
{
ammmv.zero(AMMMV_FPRIVATO);
ammmv.zero(AMMMV_QPPRIVATE);
}
// Calcolare quota ammortamento accelerato
resamm -= ammmv.get_real(AMMMV_QNOR) + ammmv.get_real(AMMMV_FPRIVATO);
if (resamm > ZERO && ammmv.get_real(AMMMV_PEACC) > ZERO && ammmv.get_real(AMMMV_QPERSE) == ZERO)
{
const real peacc = ammmv.get_real(AMMMV_PEACC);
const real qacc = calc_quota(valamm, peacc, resamm, per_eff, &rel);
ammmv.put(AMMMV_QACC, qacc);
ammmv.put(AMMMV_PEACC, per_eff);
if (tipo_sit == 1 && get_int(CESPI_USOPROM) > 1)
agg_quota(tipo_sit, valamm, ammmv, "QACC", FALSE);
else
ammmv.zero(AMMMV_FPRIVATO);
}
else
{
ammmv.zero(AMMMV_QACC);
ammmv.zero(AMMMV_PEACC);
}
// Calcolare quota ammortamento anticipato
resamm -= ammmv.get_real(AMMMV_QACC);
if (tipo() == tc_materiale && _salini.get_int(SALCE_ANNIAMM) <= 2)
{
const real peant = ammmv.get(AMMMV_PEANT);
if (resamm > ZERO && peant > ZERO && ammmv.get_real(AMMMV_QPERSE) == ZERO)
{
const real qant = calc_quota(valamm, peant, resamm, per_eff, &rel);
ammmv.put(AMMMV_QANT, qant);
ammmv.put(AMMMV_PEANT, per_eff);
if (tipo_sit == 1 && get_int(CESPI_USOPROM) > 1)
agg_quota(tipo_sit, valamm, ammmv, "QANT", FALSE);
else
ammmv.zero(AMMMV_FPRIVATO);
}
else
{
ammmv.zero(AMMMV_QANT);
ammmv.zero(AMMMV_PEANT);
}
}
}
else
{
zero_fields(ammmv, AMMMV_QNOR, AMMMV_PENOR, AMMMV_QANT, AMMMV_PEANT,
AMMMV_QACC, AMMMV_PEACC, AMMMV_FPRIVATO, AMMMV_QPERSE, AMMMV_QPPRIVATE, NULL);
}
}
}
// Calcolo ammortamento per quote
// Certified 99%
void TCespite::calc_anni(TRectype& ammmv, const TRectype& tmv, const TRectype& tmvam)
{
const int anniamm = _salini.get_int(SALCE_ANNIAMM);
const int anniric = get_int(CESPI_ANNIRIC);
if (anniamm >= anniric)
{
ammmv.zero(AMMMV_QNOR);
return;
}
const TTipo_cespite tc = tipo();
const int vincolo = get_int(CESPI_VINCOLO);
if ((tc == tc_pluriennale && vincolo == 2) ||
(tc == tc_immateriale && anniric > 0) ||
(tc == tc_materiale && anniric > 0))
{
const real qnor = mov_res_amm(tmv, tmvam) / (anniric - anniamm);
ammmv.put(AMMMV_QNOR, qnor);
} else
if (tc == tc_immateriale && vincolo == 3)
{
const real qnor = mov_val_amm(tmv) / anniric;
ammmv.put(AMMMV_QNOR, qnor);
}
const real resamm = mov_res_amm(tmv, tmvam);
real qnor = ammmv.get(AMMMV_QNOR);
if (resamm < qnor)
{
qnor = resamm;
ammmv.put(AMMMV_QNOR, qnor);
}
const real penor = qnor * 100.0 / mov_val_amm(tmv);
ammmv.put(AMMMV_PENOR, penor);
}
void TCespite::amm_mov_ven(TRelation& rel, const TRectype& tmv, const TRectype& tmvam, int tipo_sit)
{
const TTipo_cespite tc = tipo();
const bool leasing = get_bool(CESPI_LEASING);
const int anniric = get_int(CESPI_ANNIRIC);
if ((tc == tc_materiale && !leasing) || (tc == tc_immateriale && anniric == 0))
calc_perc(rel, tmv, tmvam, tipo_sit);
else
calc_anni(rel.curr(LF_AMMMV), tmv, tmvam);
rel.lfile(LF_AMMMV).rewrite();
}
void TCespite::elabora_mov_neg(TRelation& rel, TRectype& tmv, TRectype& tmvam, int tipo_sit, bool is_valid)
{
log("= Elaborazione movimento con segno -");
bool ok = null_fields(tmvam, MOVAM_QNOR, MOVAM_QANT, MOVAM_QACC,
MOVAM_QPERSE, MOVAM_QPPRIVATE, MOVAM_FPRIVATO);
if (ok)
{
if (_salpro.get_long(SALCE_NUMELE) > 0 && _salpro.get_real(SALCE_CSTO) > ZERO)
{
if (tmv.get_real(MOVCE_CSTO).is_zero())
rip_elem(rel, tmv, tmvam);
else
rip_costo(rel, tmv, tmvam);
}
}
if (is_valid && ditta_cespiti().ammortamento_parti_vendute())
{
const TString4 tpmov = tmv.get(MOVCE_CODMOV); // Tipo movimento da non confondere col tipo documento!
const TRectype& tmc = cache().get("%TMC", tpmov);
if (tmc.get_bool("B4")) // Possibile ammortamento su movimento
amm_mov_ven(rel, tmv, tmvam, tipo_sit);
else
{
TRectype& ammmv = rel.curr(LF_AMMMV);
zero_fields(ammmv, AMMMV_PNOR, AMMMV_PACC, AMMMV_PANT, AMMMV_QNOR, AMMMV_QACC,
AMMMV_QANT, AMMMV_QPERSE, AMMMV_FPRIVATO, AMMMV_QPPRIVATE, NULL);
}
rel.lfile(LF_AMMMV).rewrite();
}
}
// Scandisce tutti i movimenti del cespite fino alla data_limite
void TCespite::scansione_movimenti(int tipo_sit, const TDate& data_limite, bool is_valid)
{
log("- Scansione movimenti");
TDitta_cespiti& cce = ditta_cespiti();
TDate inies, fines;
const int esercizio = cce.esercizio_corrente(inies, fines);
TRelation rel(LF_MOVCE);
TString expr; expr << "IDCESPITE==IDCESPITE|IDMOV==IDMOV|TPAMM==\"" << tipo_sit << '"';
rel.add(LF_MOVAM, expr);
rel.add(LF_AMMMV, expr);
TRectype& movsem = rel.curr();
TRectype& movam = rel.curr(LF_MOVAM);
TRectype& ammmv = rel.curr(LF_AMMMV);
const TString idcespite = get(CESPI_IDCESPITE);
movsem.put(MOVCE_IDCESPITE, idcespite);
TString filtro;
filtro << "(IDRET==\"\")";
filtro << "&&(ANSI(DTMOV)>=\"" << inies.string(ANSI) << "\")";
if (data_limite.ok())
filtro << "&&(ANSI(DTMOV)<=\"" << data_limite.string(ANSI) << "\")";
TCursor cur(&rel, filtro, 2, &movsem, &movsem);
const long items = cur.items();
if (items > 0) // Continua solo se esistono movimenti
{
cur.freeze();
// Creo rcord campione per totale movimento + relative rettifiche
TVariable_rectype tmv(LF_MOVCE);
tmv.add_field(new TVariable_field("VSPMANU"));
// Totali ammortamenti: praticamente trattasi di estensione del record tmv
TRectype tmvam(LF_MOVAM);
for (cur = 0L; cur.pos() < items; ++cur)
{
log("= Lettura movimento %s", (const char*)movsem.get(MOVCE_IDMOV));
if (!rel.is_first_match(LF_MOVAM))
{
movam.zero();
movam.put(MOVAM_IDCESPITE, idcespite);
movam.put(MOVAM_IDMOV, movsem.get(MOVCE_IDMOV));
movam.put(MOVAM_TPAMM, tipo_sit);
rel.lfile(LF_MOVAM).write();
}
tmv = movsem;
tmvam = movam;
applica_rettifiche(tmv, tmvam, tipo_sit);
const char segno = movsem.get_char(MOVCE_SEGNO);
if (segno == '-') // Penso voglia dire vendita
{
if (!rel.is_first_match(LF_AMMMV)) // Crea ammmv se necessario
{
ammmv.zero();
ammmv.put(AMMMV_IDCESPITE, movsem.get(MOVCE_IDCESPITE));
ammmv.put(AMMMV_IDMOV, movsem.get(MOVCE_IDMOV));
ammmv.put(AMMMV_TPAMM, tipo_sit);
rel.lfile(LF_AMMMV).write();
}
elabora_mov_neg(rel, tmv, tmvam, tipo_sit, is_valid);
}
if (is_valid)
{
if (inies.year() > cce.anno_tuir()) // Controllo praticamente obsoleto
{
const int tpspeman = get_int(CESPI_TPSPEMAN);
if ((tpspeman == 2 || tpspeman == 3) || (tpspeman == 4 && cce.esente_art14()))
{
const real valamm = mov_val_amm(tmv);
real vspmanu = calcola_spese_manutenzione(valamm);
const TDate dtmov = movsem.get_date(MOVCE_DTMOV); // ???
const real giorni_residui = fines - dtmov + (segno=='-' ? 0 : 1);
const real giorni_esercizio = fines - inies + 1;
vspmanu = vspmanu * giorni_residui / giorni_esercizio;
cce.arrotonda(vspmanu);
tmv.put("VSPMANU", vspmanu);
}
}
}
else
{
tmv.zero("VSPMANU");
}
aggiorna_salpro(tmv, tmvam, segno);
}
} // If esistono movimenti
}
void TCespite::calc_amm_residui(int tipo_sit, bool is_valid)
{
log("- Calcolo ammortamenti residui");
if (!is_valid)
{
zero_fields(_ammpro, AMMCE_PNOR, AMMCE_PACC, AMMCE_PANT, AMMCE_QNOR, AMMCE_QACC, AMMCE_QANT,
AMMCE_QPERSE, AMMCE_FPRIVATO, AMMCE_QPPRIVATE, NULL);
save_amm();
return;
}
const TDitta_cespiti& cce = ditta_cespiti();
TDate inies, fines;
cce.esercizio_corrente(inies, fines);
const bool fzper = _ammpro.get_bool(AMMCE_FZPER);
const bool fzquo = _ammpro.get_bool(AMMCE_FZQUO);
const bool is_forz = fzper || fzquo; // Forzatura sul cespite
const TTipo_cespite tc = tipo();
const bool leasing = get_bool(CESPI_LEASING);
const int anniric = get_int(CESPI_ANNIRIC);
if ((tc == tc_materiale && !leasing) || (tc == tc_immateriale && anniric == 0) || is_forz)
{
const real coeff_durata = cce.coefficiente_durata_esercizio();
if (fzquo) // Forzatura quota
{
real resamm = res_amm(tipo_sit);
if (resamm > ZERO)
{
real qnor = _ammpro.get(AMMCE_QNOR);
if (resamm < qnor)
_ammpro.put(AMMCE_QNOR, qnor = resamm); // Forzo la quota uguale al residuo
const real pnor = qnor / coeff_durata * 100.0 / val_amm(tipo_sit);
_ammpro.put(AMMCE_PNOR, pnor);
resamm -= qnor + _ammpro.get_real(AMMCE_FPRIVATO);
if (resamm > ZERO)
{
real qacc = _ammpro.get(AMMCE_QACC);
if (resamm < qacc)
_ammpro.put(AMMCE_QACC, qacc = resamm); // Forzo la quota uguale al residuo
const real pacc = qacc / coeff_durata * 100.0 / val_amm(tipo_sit);
_ammpro.put(AMMCE_PACC, pacc);
resamm -= qacc;
}
else
{
zero_fields(_ammpro, AMMCE_QANT, AMMCE_PANT, AMMCE_QACC, AMMCE_PACC, NULL);
}
if (resamm > ZERO)
{
real qant = _ammpro.get(AMMCE_QANT);
if (resamm < qant)
_ammpro.put(AMMCE_QANT, qant = resamm); // Forzo la quota uguale al residuo
const real pant = qant / coeff_durata * 100.0 / val_amm(tipo_sit);
_ammpro.put(AMMCE_PANT, pant);
resamm -= qant;
}
else
{
zero_fields(_ammpro, AMMCE_QANT, AMMCE_PANT, NULL);
}
}
else
{
zero_fields(_ammpro, AMMCE_QNOR, AMMCE_PNOR, AMMCE_QANT, AMMCE_PANT, AMMCE_QACC, AMMCE_PACC,
AMMCE_QPERSE, AMMCE_FPRIVATO, AMMCE_QPPRIVATE, NULL);
}
} else
if (fzper) // Forzatura percentuale
{
real resamm = res_amm(tipo_sit);
if (resamm > ZERO)
{
const real valamm = val_amm(tipo_sit);
const real penor = _ammpro.get_real(AMMMV_PENOR);
real per_eff;
const real qnor = calc_quota(valamm, penor, resamm, per_eff);
_ammpro.put(AMMCE_QNOR, qnor);
_ammpro.put(AMMCE_PNOR, per_eff);
resamm -= qnor + _ammpro.get_real(AMMCE_FPRIVATO);
}
else
{
zero_fields(_ammpro, AMMCE_QNOR, AMMCE_PNOR, AMMCE_QANT, AMMCE_PANT, AMMCE_QACC, AMMCE_PACC,
AMMCE_QPERSE, AMMCE_FPRIVATO, AMMCE_QPPRIVATE, NULL);
}
const real pacc = _ammpro.get(AMMCE_PACC);
if (resamm > ZERO && pacc > ZERO)
{
const real valamm = val_amm(tipo_sit);
real per_eff;
const real qacc = calc_quota(valamm, pacc, resamm, per_eff);
_ammpro.put(AMMCE_QACC, qacc);
_ammpro.put(AMMCE_PACC, per_eff);
resamm -= qacc;
}
else
zero_fields(_ammpro, AMMCE_QACC, AMMCE_PACC, NULL);
const real pant = _ammpro.get(AMMCE_PANT);
if (resamm > ZERO && pant > ZERO)
{
const real valamm = val_amm(tipo_sit);
real per_eff;
const real qant = calc_quota(valamm, pant, resamm, per_eff);
_ammpro.put(AMMCE_QANT, qant);
_ammpro.put(AMMCE_PANT, per_eff);
resamm -= qant;
}
else
zero_fields(_ammpro, AMMCE_QANT, AMMCE_PANT, NULL);
}
else // Nessuna forzatura
{
_ammpro.put(AMMCE_PNOR, _ammini.get(AMMCE_PNOR));
_ammpro.put(AMMCE_PANT, _ammini.get(AMMCE_PANT));
_ammpro.put(AMMCE_PACC, _ammini.get(AMMCE_PACC));
// Percentuale minima quote perse
real pmat = get_real(CESPI_PMAT) / 2.0;
const TDate dtfunz = get(CESPI_DTFUNZ);
if (tc == tc_materiale && _salini.get_int(SALCE_ANNIAMM) == 0 &&
!cce.professionista() && dtfunz >= inies)
{
// Calcolo il valore di un singolo elemento (se non nullo!)
real vam = val_amm(tipo_sit);
if (vam > ZERO)
{
const real numele = _salpro.get(SALCE_NUMELE);
if (numele > ZERO)
vam /= numele;
}
if (_ammini.get_bool(AMMCE_CSCEN) && vam < un_milione())
{
_ammpro.put(AMMCE_PNOR, "100");
_ammpro.zero(AMMCE_PANT); _ammpro.zero(AMMCE_PACC);
_ammpro.put(AMMCE_MSG04, "X");
}
else
{
_ammpro.put(AMMCE_PNOR, _ammini.get_real(AMMCE_PNOR)/2.0);
_ammpro.put(AMMCE_PANT, _ammini.get_real(AMMCE_PANT)/2.0);
_ammpro.put(AMMCE_PACC, _ammini.get_real(AMMCE_PACC)/2.0);
_ammpro.put(AMMCE_MSG01, "X");
pmat = get_real(CESPI_PMAT) / 4.0;
}
}
real resamm = res_amm(tipo_sit);
if (resamm > ZERO)
{
const real valamm = val_amm(tipo_sit);
const real pnor = _ammpro.get(AMMCE_PNOR);
real per_eff;
const real qnor = calc_quota(valamm, pnor, resamm, per_eff);
_ammpro.put(AMMCE_QNOR, qnor);
_ammpro.put(AMMCE_PNOR, per_eff);
const real quote_perse = calc_quote_perse(valamm, pmat, resamm, qnor, FALSE, TDate());
_ammpro.put(AMMCE_QPERSE, quote_perse);
const int uso_promiscuo = get_int(CESPI_USOPROM);
if (tipo_sit == 1 && uso_promiscuo > 1)
agg_quota(tipo_sit, valamm, _ammpro, "QNOR", TRUE);
else
zero_fields(_ammpro, AMMCE_FPRIVATO, AMMCE_QPPRIVATE, NULL);
resamm -= qnor + _ammpro.get_real(AMMCE_FPRIVATO);
const real pacc = _ammpro.get_real(AMMCE_PACC);
if (resamm > ZERO && pacc > ZERO && quote_perse == ZERO)
{
const real qacc = calc_quota(val_amm(tipo_sit), pacc, resamm, per_eff);
_ammpro.put(AMMCE_QACC, qacc);
_ammpro.put(AMMCE_PACC, per_eff);
if (tipo_sit == 1 && uso_promiscuo > 1)
agg_quota(tipo_sit, valamm, _ammpro, "QACC", FALSE);
else
_ammpro.zero(AMMCE_FPRIVATO);
resamm -= qacc;
}
else
zero_fields(_ammpro, AMMCE_PACC, AMMCE_QACC, NULL);
const int anniamm = _salini.get_int(SALCE_ANNIAMM);
if (tc != tc_materiale || anniamm > 2)
{
zero_fields(_ammpro, AMMCE_PANT, AMMCE_QANT, NULL);
}
else
{
const real pant = _ammpro.get_real(AMMCE_PANT);
if (resamm > ZERO && pant > ZERO)
{
const real qant = calc_quota(val_amm(tipo_sit), pant, resamm, per_eff);
_ammpro.put(AMMCE_QANT, qant);
_ammpro.put(AMMCE_PANT, per_eff);
if (tipo_sit == 1 && uso_promiscuo > 1)
agg_quota(tipo_sit, valamm, _ammpro, "QANT", FALSE);
else
_ammpro.zero(AMMCE_FPRIVATO);
}
else
zero_fields(_ammpro, AMMCE_PANT, AMMCE_QANT, NULL);
}
}
else
{
zero_fields(_ammpro, AMMCE_PNOR, AMMCE_PACC, AMMCE_PANT, AMMCE_QNOR, AMMCE_QACC, AMMCE_QANT,
AMMCE_QPERSE, AMMCE_FPRIVATO, AMMCE_QPPRIVATE, NULL);
}
}
}
else
{
// Calcolo ammortamenti per anni
real resamm = res_amm(tipo_sit);
if (resamm > ZERO)
{
const int anniamm = _salini.get_int(SALCE_ANNIAMM);
const int vincolo = get_int(CESPI_VINCOLO);
real qnor; // Valore non calcolato
if ((tc == tc_pluriennale && vincolo == 2 && _ammini.get_real(AMMCE_PNOR).is_zero()) ||
(tc == tc_immateriale && anniric > 0) || (tc == tc_materiale && anniric > 0))
{
if (anniric > anniamm)
qnor = resamm / (anniric - anniamm);
} else
if (tc == tc_pluriennale && vincolo == 3)
{
if (anniric > anniamm)
qnor = val_amm(tipo_sit) / anniric;
} else
if (tc == tc_pluriennale && vincolo == 1)
{
if (anniric > 0)
qnor = val_amm(tipo_sit) / anniric;
else
qnor = val_amm(tipo_sit) * _ammini.get_real(AMMCE_PNOR) / 100.0;
} else
if (tc == tc_pluriennale && vincolo == 2 && _ammini.get_real(AMMCE_PNOR) > ZERO)
{
if (anniric > anniamm)
qnor = val_amm(tipo_sit) * _ammini.get_real(AMMCE_PNOR) / 100.0;
}
if (resamm < qnor)
qnor = resamm;
cce.arrotonda(qnor);
_ammpro.put(AMMCE_QNOR, qnor);
const real valore = val_amm(tipo_sit);
if (qnor > ZERO && valore > ZERO)
{
const real pnor = qnor * 100.0 / valore;
_ammpro.put(AMMCE_PNOR, pnor);
}
else
_ammpro.zero(AMMCE_PNOR);
}
else
{
_ammpro.zero(AMMCE_PNOR);
_ammpro.zero(AMMCE_QNOR);
}
}
save_amm();
}
void TCespite::agg_spe_man(int tipo_sit, bool is_valid)
{
if (tipo_sit != 1 || !is_valid || tipo() != tc_materiale)
return;
log("- Aggiornamento spese di manutenzione");
TDitta_cespiti& cce = ditta_cespiti();
TString16 field; // Nome del campo da incrementare
const int tpspeman = get_int(CESPI_TPSPEMAN);
if (tpspeman == 2 || (tpspeman == 4 && !cce.esente_art14()))
field = "R2"; else
if (tpspeman == 3)
field = "R3";
const real vspmanu = _salpro.get_real(SALCE_VSPMANU);
if (field.not_empty() && vspmanu > ZERO)
{
int es;
TString4 gr, sp;
cce.get_attivita(es, gr, sp);
TString16 key;
key.format("%04d%s%s", es, (const char*)gr, (const char*)sp);
TTable ccb("CCB");
ccb.put("CODTAB", key);
const int err = ccb.read();
if (err != NOERR)
{
ccb.zero();
ccb.put("CODTAB", key);
}
real speman = ccb.get(field);
speman += vspmanu;
ccb.put(field, speman);
ccb.put("D0", TDate(TODAY));
if (err == NOERR)
ccb.rewrite();
else
ccb.write();
}
}
bool TCespite::calc_amm(int tipo_sit, bool recalc_spe_man, const TDate& data_limite)
{
const TString16 idcespite = get(CESPI_IDCESPITE); // Keep it handy for debug purposes
log("* Inizio calcolo situazione %d cespite %s", tipo_sit, (const char*)idcespite);
#ifdef DBG
if (tipo_sit == 1 && atol(idcespite) == 28L)
tipo_sit = 1; // Put your breakpoint here
#endif
const bool is_valid = valido(tipo_sit);
prepara_saldi(tipo_sit, is_valid);
scansione_movimenti(tipo_sit, data_limite, is_valid);
calc_amm_residui(tipo_sit, is_valid);
if (recalc_spe_man)
agg_spe_man(tipo_sit, is_valid);
log("* Fine calcolo situazione %d cespite %s", tipo_sit, (const char*)idcespite);
log("");
return is_valid;
}
int TCespite::read(const char* id)
{
TLocalisamfile cespi(LF_CESPI);
put(CESPI_IDCESPITE, id);
int err = TRectype::read(cespi, _isequal, _nolock);
if (err != NOERR)
zero();
_salini.zero(); _salpro.zero();
_ammini.zero(); _ammpro.zero();
return err;
}
TCespite::TCespite()
: TRectype(LF_CESPI), _salini(LF_SALCE), _salpro(LF_SALCE), _ammini(LF_AMMCE), _ammpro(LF_AMMCE)
{
}
TCespite::TCespite(const char* id)
: TRectype(LF_CESPI), _salini(LF_SALCE), _salpro(LF_SALCE), _ammini(LF_AMMCE), _ammpro(LF_AMMCE)
{
read(id);
}
TCespite::TCespite(const TRectype& rec)
: TRectype(LF_CESPI), _salini(LF_SALCE), _salpro(LF_SALCE), _ammini(LF_AMMCE), _ammpro(LF_AMMCE)
{
TRectype::operator=(rec);
}