7859fe8aa2
Files correlati : Ricompilazione Demo : [ ] Commento : 0000791: contabilizzazione vendita cespite Descrizione nella registrazione contabile risultante dalla vendita cespite non vengono compilati i campi n. e data documento, che nel movimento di vendita sono compilati. git-svn-id: svn://10.65.10.50/trunk@16137 c028cbd2-c16b-5b4b-a496-9718f37d4682
1014 lines
32 KiB
C++
Executable File
1014 lines
32 KiB
C++
Executable File
#include <applicat.h>
|
|
#include <automask.h>
|
|
#include <progind.h>
|
|
#include <reprint.h>
|
|
#include <reputils.h>
|
|
|
|
#include "../cg/cg2101.h"
|
|
#include "../cg/cglib02.h"
|
|
|
|
#include "celib.h"
|
|
#include "ce2101.h"
|
|
|
|
#include "ce4400a.h"
|
|
|
|
#include "ammce.h"
|
|
#include "cespi.h"
|
|
#include "movam.h"
|
|
#include "movce.h"
|
|
|
|
//===============================================================================================
|
|
//maschera
|
|
|
|
class TTrasf_mov_ce_cg_mask: public TAutomask
|
|
{
|
|
protected:
|
|
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
|
|
|
|
public:
|
|
TTrasf_mov_ce_cg_mask():TAutomask("ce4400a") { ditta_cespiti().init_mask(*this); }
|
|
|
|
};
|
|
|
|
bool TTrasf_mov_ce_cg_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
|
{
|
|
switch (o.dlg())
|
|
{
|
|
case F_DATACALC:
|
|
if (e == fe_close)
|
|
{
|
|
const TDate data_fine_es = get(F_FINE_ES);
|
|
const TDate data_ini_es = get(F_INIZIO_ES);
|
|
TDate datacalc = o.get();
|
|
if (datacalc < data_ini_es)
|
|
return error_box("La data di calcolo deve essere pari o successiva alla data inizio dell'esercizio selezionato");
|
|
if (!datacalc.ok())
|
|
{
|
|
datacalc = data_fine_es;
|
|
o.set(datacalc.string());
|
|
}
|
|
|
|
if (datacalc < data_ini_es || datacalc > data_fine_es)
|
|
return error_box(TR("La data di calcolo deve appartenere all'esercizio selezionato!"));
|
|
}
|
|
break;
|
|
case F_DATAREG:
|
|
if (e == fe_modify || e == fe_close)
|
|
{
|
|
const int ese = get_int(F_ESERCIZIO);
|
|
TDate datalim;
|
|
TEsercizi_contabili esc;
|
|
const int nesen = esc.next(ese);
|
|
if (nesen > 0)
|
|
{
|
|
datalim = esc[nesen].fine();
|
|
}
|
|
else
|
|
{
|
|
datalim = esc[ese].fine();
|
|
datalim.addyear(1);
|
|
}
|
|
TDate datareg = o.get();
|
|
if (datareg > datalim)
|
|
return error_box(FR("La data registrazione deve essere inferiore al %s"), datalim.string());
|
|
|
|
}
|
|
default: break;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
//==============================================================================================
|
|
// Metodi static che servono in giro
|
|
|
|
static long get_new_numreg()
|
|
{
|
|
TLocalisamfile mov(LF_MOV);
|
|
mov.last();
|
|
//primo numero libero da usare come numreg
|
|
return mov.curr().get_long(MOV_NUMREG) + 1;
|
|
}
|
|
|
|
static void fill_head(TRectype& head, const TDate& datacomp, const TDate& datareg,
|
|
const long numreg, const TString& codcaus, const bool definitivo,
|
|
const TString& numdoc, const TString& tipodoc, const TDate& datadoc)
|
|
{
|
|
TEsercizi_contabili esc;
|
|
const int codes = esc.date2esc(datacomp);
|
|
head.put(MOV_ANNOES, codes);
|
|
head.put(MOV_NUMREG, numreg);
|
|
head.put(MOV_DATAREG, datareg);
|
|
head.put(MOV_DATACOMP, datacomp);
|
|
head.put(MOV_CODCAUS, codcaus);
|
|
//campi dei soli movimenti di vendita/eliminazione
|
|
head.put(MOV_NUMDOC, numdoc);
|
|
head.put(MOV_TIPODOC, tipodoc);
|
|
head.put(MOV_DATADOC, datadoc);
|
|
|
|
if (!definitivo)
|
|
head.put(MOV_PROVVIS, 'C');
|
|
}
|
|
|
|
|
|
//===============================================================================================
|
|
//Rectype da utilizzare per la creazione delle righe movimento contabili. Deriva da LF_RMOV ma ha..
|
|
//..3 valori in piu' (gruppo,specie,categoria) che servono per gli ordinamenti in fase di generazione..
|
|
//..movimenti contabili
|
|
class TRigamov : public TRectype
|
|
{
|
|
TString4 _spc;
|
|
int _grp, _cat;
|
|
|
|
public:
|
|
virtual int compare(const TSortable& s) const;
|
|
const TRectype& categoria() const;
|
|
const TString& descr_categoria() const;
|
|
TRigamov(const int grp, const TString& spc, const int cat)
|
|
: TRectype(LF_RMOV) { _grp = grp; _spc = spc; _cat = cat; }
|
|
};
|
|
|
|
|
|
const TRectype& TRigamov::categoria() const
|
|
{
|
|
return ditta_cespiti().categoria(_grp, _spc, _cat, true);
|
|
}
|
|
|
|
const TString& TRigamov::descr_categoria() const
|
|
{
|
|
TString& wrkstring = get_tmp_string();
|
|
wrkstring << _grp << ' ' << _spc << ' ' << _cat << ' ' ;
|
|
wrkstring << ditta_cespiti().categoria(_grp, _spc, _cat, false).get("S0");
|
|
return wrkstring;
|
|
}
|
|
|
|
//confrontatore di saldi_per_codice
|
|
int TRigamov::compare(const TSortable& s) const
|
|
{
|
|
int cmp = 0;
|
|
const TRigamov& sc = (const TRigamov&)s;
|
|
cmp = _grp - sc._grp;
|
|
if (cmp == 0)
|
|
{
|
|
cmp = _spc.compare(sc._spc);
|
|
if (cmp == 0)
|
|
cmp = _cat - sc._cat;
|
|
|
|
}
|
|
|
|
return cmp;
|
|
}
|
|
|
|
//===============================================================================================
|
|
//Struct che serve per avere ammortamenti per categoria (Codcat|Qamm_tot|Qperse_tot)
|
|
struct TSaldo_per_codice :public TSortable
|
|
{
|
|
TString4 _spc;
|
|
int _grp, _cat;
|
|
TString16 _idcespite;
|
|
real _qnor, _qant, _qacc;//, _qperse;
|
|
void add(const TRectype& rec_ammce);
|
|
|
|
virtual int compare(const TSortable& s) const;
|
|
const TRectype& categoria() const;
|
|
const TString& descr_categoria() const;
|
|
|
|
int compila_rmov(const int tipo, const int riga_nor, TArray& righe_mov, TLog_report& log, const int movdett) const;
|
|
int genera_righe(TArray& righe_mov, TLog_report& log, const int movdett) const;
|
|
|
|
TSaldo_per_codice(const int grp, const TString& spc, const int cat, const char* idcespite = "")
|
|
: _grp(grp),_spc(spc), _cat(cat), _idcespite(idcespite) {}
|
|
};
|
|
|
|
void TSaldo_per_codice::add(const TRectype& rec_ammce)
|
|
{
|
|
//valore totale degli ammortamenti del cespite di tipo qnor,qant,qacc che trova in AMMCE
|
|
const real qnor = rec_ammce.get_real(AMMCE_QNOR);
|
|
const real qant = rec_ammce.get_real(AMMCE_QANT);
|
|
const real qacc = rec_ammce.get_real(AMMCE_QACC);
|
|
//valore totale delle qperse del cespite che trova in AMMCE
|
|
//const real qperse = rec_ammce.get_real(AMMCE_QPERSE);
|
|
|
|
_qnor += qnor;
|
|
_qant += qant;
|
|
_qacc += qacc;
|
|
// _qperse += qperse;
|
|
}
|
|
|
|
//confrontatore di saldi_per_codice
|
|
int TSaldo_per_codice::compare(const TSortable& s) const
|
|
{
|
|
int cmp = 0;
|
|
const TSaldo_per_codice& sc = (const TSaldo_per_codice&)s;
|
|
cmp = _grp - sc._grp;
|
|
if (cmp == 0)
|
|
{
|
|
cmp = _spc.compare(sc._spc);
|
|
if (cmp == 0)
|
|
{
|
|
cmp = _cat - sc._cat;
|
|
if (cmp == 0)
|
|
cmp = _idcespite.compare(sc._idcespite);
|
|
}
|
|
}
|
|
|
|
return cmp;
|
|
}
|
|
|
|
bool str2bill(const TString& stringona, const int pos, TBill& zio)
|
|
{
|
|
const int gr = atoi(stringona.mid(pos, 3));
|
|
const int co = atoi(stringona.mid(pos+3, 3));
|
|
if (co <= 0)
|
|
return false;
|
|
const long so = atoi(stringona.mid(pos+6, 6));
|
|
zio.set(gr, co, so);
|
|
return true;
|
|
}
|
|
|
|
int TSaldo_per_codice::compila_rmov(const int tipo, const int riga_nor, TArray& righe_mov, TLog_report& log,
|
|
const int movdett) const
|
|
{
|
|
int pos = 0;
|
|
const char* field = "S1";
|
|
real quota;
|
|
switch (tipo)
|
|
{
|
|
case 1: quota = _qnor; pos = 24; break;
|
|
case 2: quota = _qant; pos = 36; break;
|
|
case 3: quota = _qacc; pos = 48; break;
|
|
default: break;
|
|
}
|
|
if (quota <= ZERO)
|
|
return -1;
|
|
|
|
const TRectype& rec_ccc = categoria();
|
|
const TString& stringona = rec_ccc.get(field);
|
|
TBill zio;
|
|
if (!str2bill(stringona, pos, zio))
|
|
{
|
|
pos = 24;
|
|
if (tipo == 1 || !str2bill(stringona, pos, zio))
|
|
{
|
|
TString msg;
|
|
msg << TR("Manca il conto per le quote ammortamento normali della categoria ") << descr_categoria();
|
|
log.log(2, msg);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
if (pos == 24 && riga_nor >= 0)
|
|
{
|
|
TRectype& rmovnor = (TRectype&)righe_mov[riga_nor];
|
|
rmovnor.add(RMV_IMPORTO, quota);
|
|
return riga_nor;
|
|
}
|
|
|
|
TRigamov* rmov = new TRigamov(_grp, _spc, _cat);
|
|
rmov->put(RMV_SEZIONE, "D");
|
|
rmov->put(RMV_IMPORTO, quota);
|
|
//conto e descrizione dipendono dal livello di dettaglio stabilito nella configurazione del collegamento CG/CE
|
|
switch (movdett)
|
|
{
|
|
case 0: //dettaglio per categoria
|
|
rmov->put(RMV_DESCR, rmov->descr_categoria());
|
|
break;
|
|
case 1: //dettaglio per cespite
|
|
{
|
|
const TRectype& rec_cespi = cache().get(LF_CESPI, _idcespite);
|
|
rmov->put(RMV_DESCR, rec_cespi.get(CESPI_DESC));
|
|
}
|
|
break;
|
|
case 2: //dettaglio per cespite con sottoconto=idcespite (idcespite numerico e di 6 cifre max!)
|
|
{
|
|
const TRectype& rec_cespi = cache().get(LF_CESPI, _idcespite);
|
|
rmov->put(RMV_DESCR, rec_cespi.get(CESPI_DESC));
|
|
bool ok = real::is_natural(_idcespite);
|
|
if (ok)
|
|
{
|
|
const long sottoc = atol(_idcespite);
|
|
ok = sottoc > 0 && sottoc < 1000000;
|
|
if (ok)
|
|
{
|
|
zio.set(zio.gruppo(), zio.conto(), sottoc);
|
|
ok = zio.find();
|
|
}
|
|
}
|
|
if (!ok)
|
|
{
|
|
TString msg;
|
|
msg.format(FR("Il codice cespite %s non e' un sottoconto valido"), (const char*)_idcespite);
|
|
log.log(2, msg);
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
zio.put(*rmov);
|
|
|
|
return righe_mov.add(rmov);
|
|
}
|
|
|
|
//metodo di alto livello per la compilazione delle righe contabili;chiama il metodo di basso livello..
|
|
//..compila_rmov con i parametri caso x caso
|
|
int TSaldo_per_codice::genera_righe(TArray& righe_mov, TLog_report& log, const int movdett) const
|
|
{
|
|
const int righe_prima = righe_mov.items();
|
|
const int riga_nor = compila_rmov(1, -1, righe_mov, log, movdett);
|
|
const int riga_ant = compila_rmov(2, riga_nor, righe_mov, log, movdett);
|
|
const int riga_acc = compila_rmov(3, riga_nor, righe_mov, log, movdett);
|
|
// const int riga_persa = compila_rmov(4, -1, righe_mov, log, movdett);
|
|
|
|
const int righe_dopo = righe_mov.items();
|
|
return righe_dopo - righe_prima; //messo qui tanto per poter compilare
|
|
}
|
|
|
|
const TRectype& TSaldo_per_codice::categoria() const
|
|
{
|
|
//viene chiamato il metodo standard della ditta_cespiti con l'ultimo parametro true in modo che usi solo...
|
|
//...le categorie valide per il collegamento alla contabilita' (tabella CCC)
|
|
return ditta_cespiti().categoria(_grp, _spc, _cat, true);
|
|
}
|
|
|
|
const TString& TSaldo_per_codice::descr_categoria() const
|
|
{
|
|
TString& wrkstring = get_tmp_string();
|
|
wrkstring << _grp << ' ' << _spc << ' ' << _cat << ' ' ;
|
|
wrkstring << ditta_cespiti().categoria(_grp, _spc, _cat, false).get("S0");
|
|
return wrkstring;
|
|
}
|
|
|
|
//===============================================================================================
|
|
//TMovimentoPN_CE
|
|
|
|
class TMovimentoPN_CE : public TMovimentoPN
|
|
{
|
|
TSaldo_agg _sagg;
|
|
|
|
protected:
|
|
void salda_rmov(const bool add);
|
|
|
|
public:
|
|
virtual int read(TIsamop op = _isequal, TReclock lockop = _nolock);
|
|
virtual int write(bool force = true);
|
|
virtual int rewrite(bool force = true);
|
|
virtual int remove();
|
|
|
|
TRectype& nuova_riga();
|
|
TRectype& nuova_riga(const TRectype& row);
|
|
};
|
|
|
|
void TMovimentoPN_CE::salda_rmov(const bool add)
|
|
{
|
|
_sagg.set_anno_es(curr().get_int(MOV_ANNOES));
|
|
_sagg.set_movprovv(curr().get_char(MOV_PROVVIS) > ' ');
|
|
_sagg.set_movimentato(true);
|
|
|
|
TBill zio;
|
|
TImporto imp;
|
|
for (int i = 0; i < cg_items(); i++)
|
|
{
|
|
const TRectype& rmov = cg(i); //riga i-esima corrente
|
|
zio.get(rmov);
|
|
imp.set(rmov.get_char(RMV_SEZIONE), rmov.get_real(RMV_IMPORTO));
|
|
_sagg.aggiorna(zio, imp, add);
|
|
}
|
|
}
|
|
|
|
int TMovimentoPN_CE::read(TIsamop op, TReclock lockop)
|
|
{
|
|
int err = TMovimentoPN::read(op, lockop);
|
|
if (err == NOERR)
|
|
{
|
|
_sagg.reset();
|
|
salda_rmov(false);
|
|
}
|
|
return err;
|
|
}
|
|
|
|
int TMovimentoPN_CE::remove()
|
|
{
|
|
int err = TMovimentoPN::remove();
|
|
if (err == NOERR)
|
|
{
|
|
_sagg.registra();
|
|
_sagg.reset();
|
|
}
|
|
return err;
|
|
}
|
|
|
|
int TMovimentoPN_CE::write(bool force)
|
|
{
|
|
int err = TMovimentoPN::write(force);
|
|
if (err == NOERR)
|
|
{
|
|
salda_rmov(true);
|
|
_sagg.set_num_ulmov(curr().get_long(MOV_NUMREG));
|
|
_sagg.set_data_ulmov(curr().get_date(MOV_DATAREG));
|
|
_sagg.registra();
|
|
}
|
|
return err;
|
|
}
|
|
|
|
int TMovimentoPN_CE::rewrite(bool force)
|
|
{
|
|
int err = TMovimentoPN::rewrite(force);
|
|
if (err == NOERR)
|
|
{
|
|
salda_rmov(true);
|
|
_sagg.registra();
|
|
}
|
|
return err;
|
|
}
|
|
|
|
//nuova riga fondo
|
|
TRectype& TMovimentoPN_CE::nuova_riga()
|
|
{
|
|
TRectype& riga = cg(-1);
|
|
riga.put(RMV_NUMRIG, cg_items());
|
|
riga.put(RMV_ANNOES, curr().get(MOV_ANNOES));
|
|
|
|
return riga;
|
|
}
|
|
|
|
//nuova riga normale
|
|
TRectype& TMovimentoPN_CE::nuova_riga(const TRectype& row)
|
|
{
|
|
TRectype& riga = cg(-1);
|
|
riga = row;
|
|
riga.put(RMV_NUMRIG, cg_items());
|
|
riga.put(RMV_ANNOES, curr().get(MOV_ANNOES));
|
|
|
|
//resettatore del saldo ad ogni nuovo movimento (righe tot presenti 1 = nuovo movimento)
|
|
if (cg_items() == 1)
|
|
_sagg.reset();
|
|
|
|
return riga;
|
|
}
|
|
|
|
|
|
//===============================================================================================
|
|
//TAmmortamento_per_cespite
|
|
|
|
class TPlus_minus : public TSaldo_per_codice
|
|
{
|
|
TArray _ammmv, _movam, _movce;
|
|
|
|
public:
|
|
void genera_mov_elim_ven(TConfig& config_ditta_ce, const TDate& datacomp, const TDate& datareg,
|
|
const bool definitivo, TLog_report& log) const;
|
|
TPlus_minus(const int gruppo, const TString& specie, const int categoria,
|
|
const TArray& ammmv, const TArray& movam, const TArray& movce)
|
|
: TSaldo_per_codice(gruppo, specie, categoria), _ammmv(ammmv), _movam(movam), _movce(movce) {}
|
|
};
|
|
|
|
//metodo per la generazione dei movimenti dovuti a plus/minus
|
|
void TPlus_minus::genera_mov_elim_ven(TConfig& config_ditta_ce, const TDate& datacomp, const TDate& datareg,
|
|
const bool definitivo, TLog_report& log) const
|
|
{
|
|
//parametri da utilizzare piu' volte
|
|
TString4 codcaus;
|
|
//conti fondo, immobilizzo, sopravenienza passiva, plusvalenza, minusvalenza cespite
|
|
const TString& stringona = categoria().get("S1");
|
|
|
|
TBill zio_fondo;
|
|
str2bill(stringona, 12, zio_fondo);
|
|
if (!zio_fondo.find())
|
|
{
|
|
TString msg;
|
|
msg << TR("Conto del fondo errato o mancante per la categoria ") << descr_categoria();
|
|
log.log(2, msg);
|
|
return;
|
|
}
|
|
TBill zio_immobilizzo;
|
|
str2bill(stringona, 0, zio_immobilizzo);
|
|
if (!zio_immobilizzo.find())
|
|
{
|
|
TString msg;
|
|
msg << TR("Conto di immobilizzo errato o mancante per la categoria ") << descr_categoria();
|
|
log.log(2, msg);
|
|
return;
|
|
}
|
|
|
|
//Riempie i campi della testata movimento
|
|
long numreg = get_new_numreg();
|
|
|
|
//attenzione!! ci possono essere piu' movimenti per lo stesso cespite!!! -> ciclo sui movce.items()
|
|
for (int i = 0; i < _movce.items(); i++)
|
|
{
|
|
const TRectype& movce = (const TRectype&)_movce[i];
|
|
const TRectype& movam = (const TRectype&)_movam[i];
|
|
|
|
//causale movimento
|
|
const real impven = movce.get_real(MOVCE_IMPVEN);
|
|
const bool eliminazione = impven == ZERO;
|
|
|
|
//estremi documento di vendita
|
|
const TString& numdoc = movce.get(MOVCE_NDOC);
|
|
const TString& tipodoc = movce.get(MOVCE_TPDOC);
|
|
const TDate& datadoc = movce.get_date(MOVCE_DTDOC);
|
|
|
|
if (eliminazione)
|
|
codcaus = config_ditta_ce.get("COAUEL");
|
|
else
|
|
codcaus = config_ditta_ce.get("COAUCH");
|
|
|
|
if (codcaus.empty())
|
|
{
|
|
TString msg;
|
|
msg << TR("Causale di vendita o eliminazione mancante");
|
|
log.log(2, msg);
|
|
return;
|
|
}
|
|
|
|
//movimento contabile
|
|
TMovimentoPN_CE pn;
|
|
TRectype& head = pn.curr();
|
|
|
|
fill_head(head, datacomp, datareg, numreg, codcaus, definitivo, numdoc, tipodoc, datadoc);
|
|
head.put(MOV_DESCR, movce.get(MOVCE_DESC));
|
|
numreg ++; //incrementa il numreg per l'eventuale testata successiva
|
|
|
|
//Aggiunge le righe
|
|
//le prime 2 righe sono comuni a tutti i tipi di movimento (esistono solo con importo non nullo)
|
|
|
|
//riga 1: fondo
|
|
const real val_fondo_cesp = movam.get_real(MOVAM_QNOR) + movam.get_real(MOVAM_QANT) + movam.get_real(MOVAM_QACC);
|
|
if (!val_fondo_cesp.is_zero())
|
|
{
|
|
TRectype& riga_fondo = pn.nuova_riga();
|
|
riga_fondo.put(RMV_SEZIONE, 'D');
|
|
riga_fondo.put(RMV_IMPORTO, val_fondo_cesp); //somma qnor+qant+qacc in movam);
|
|
zio_fondo.put(riga_fondo);
|
|
riga_fondo.put(RMV_DESCR, TR("Fondo"));
|
|
}
|
|
|
|
//riga 2: immobilizzo
|
|
const real val_imm_cesp = movce.get_real(MOVCE_CSTO);
|
|
if (!val_imm_cesp.is_zero())
|
|
{
|
|
TRectype& riga_immobilizzo = pn.nuova_riga();
|
|
riga_immobilizzo.put(RMV_SEZIONE, 'A');
|
|
riga_immobilizzo.put(RMV_IMPORTO, val_imm_cesp);
|
|
zio_immobilizzo.put(riga_immobilizzo);
|
|
riga_immobilizzo.put(RMV_DESCR, TR("Immobilizzo"));
|
|
}
|
|
|
|
//le successive righe dipendono dai parametri del config_ditta_ce e dalla differenza di importi riga2-riga1
|
|
const real val_sopravv_pass = val_imm_cesp - val_fondo_cesp;
|
|
if (eliminazione) //caso di ELIMINAZIONE cespite:
|
|
{
|
|
//riga 3: sopravenienza passiva (SOLO se movimento sbilanciato!)
|
|
if (!val_sopravv_pass.is_zero())
|
|
{
|
|
TRectype& riga_sopravv = pn.nuova_riga();
|
|
riga_sopravv.put(RMV_SEZIONE, 'D');
|
|
riga_sopravv.put(RMV_IMPORTO, val_sopravv_pass);
|
|
TBill zio_sopravv(config_ditta_ce.get_int("GRCOTELI"), config_ditta_ce.get_int("COCOTELI"),
|
|
config_ditta_ce.get_long("SOCOTELI"));
|
|
if (!zio_sopravv.find())
|
|
{
|
|
TString msg;
|
|
msg << TR("Conto di sopravvenienza errato o mancante");
|
|
log.log(2, msg);
|
|
return;
|
|
}
|
|
zio_sopravv.put(riga_sopravv);
|
|
riga_sopravv.put(RMV_DESCR, TR("Sopravenienza passiva"));
|
|
}
|
|
}
|
|
else //caso di VENDITA cespite:
|
|
{
|
|
//riga 3: vendita; parte comune (anche questa, come le altre, deve avere importo non nullo)
|
|
if (!impven.is_zero())
|
|
{
|
|
TRectype& riga_ven = pn.nuova_riga();
|
|
riga_ven.put(RMV_SEZIONE, 'D');
|
|
riga_ven.put(RMV_IMPORTO, impven);
|
|
|
|
const bool tiposcrit = config_ditta_ce.get_bool("COR5PM");
|
|
if (tiposcrit) //tipo scrittura per vendita: su conto cespite (conto in categoria CCC)
|
|
{
|
|
zio_immobilizzo.put(riga_ven);
|
|
riga_ven.put(RMV_DESCR, TR("Vendita su conto cespite"));
|
|
}
|
|
else //tipo scrittura per vendita: su conto vendita (conto in configurazione ditta)
|
|
{
|
|
TBill zio_vendita(config_ditta_ce.get_int("GRCOTVEN"), config_ditta_ce.get_int("COCOTVEN"),
|
|
config_ditta_ce.get_long("SOCOTVEN"));
|
|
if (!zio_vendita.find())
|
|
{
|
|
TString msg;
|
|
msg << TR("Conto di vendita cespite errato o mancante");
|
|
log.log(2, msg);
|
|
return;
|
|
}
|
|
zio_vendita.put(riga_ven);
|
|
riga_ven.put(RMV_DESCR, TR("Vendita su conto vendita"));
|
|
}
|
|
} //if(!impven.is_zero...
|
|
|
|
//riga 4: plus/minus-valenza
|
|
TImporto imp_fondo('D', val_fondo_cesp);
|
|
TImporto imp_immobilizzo('A', val_imm_cesp);
|
|
TImporto imp_ven('D', impven);
|
|
TImporto imp_valenza = imp_fondo;
|
|
imp_valenza += imp_immobilizzo;
|
|
imp_valenza += imp_ven;
|
|
|
|
if (!imp_valenza.is_zero()) //SOLO se movimento sbilanciato dopo le prime 3 righe, ovvero come le precedenti
|
|
{
|
|
imp_valenza.swap_section();
|
|
imp_valenza.normalize();
|
|
|
|
TRectype& riga_valenza = pn.nuova_riga();
|
|
const char sezione_valenza = imp_valenza.sezione();
|
|
riga_valenza.put(RMV_SEZIONE, sezione_valenza);
|
|
riga_valenza.put(RMV_IMPORTO, imp_valenza.valore());
|
|
|
|
if (sezione_valenza == 'A') //plusvalenza
|
|
{
|
|
TBill zio_plus(config_ditta_ce.get_int("GRCOTPLU"), config_ditta_ce.get_int("COCOTPLU"),
|
|
config_ditta_ce.get_long("SOCOTPLU"));
|
|
if (!zio_plus.find())
|
|
{
|
|
TString msg;
|
|
msg << TR("Conto di plusvalenza errato o mancante");
|
|
log.log(2, msg);
|
|
return;
|
|
}
|
|
zio_plus.put(riga_valenza);
|
|
riga_valenza.put(RMV_DESCR, TR("Plusvalenza"));
|
|
}
|
|
else //minusvalenza
|
|
{
|
|
TBill zio_minus(config_ditta_ce.get_int("GRCOTMIN"), config_ditta_ce.get_int("COCOTMIN"),
|
|
config_ditta_ce.get_long("SOCOTMIN"));
|
|
if (!zio_minus.find())
|
|
{
|
|
TString msg;
|
|
msg << TR("Conto di minusvalenza errato o mancante");
|
|
log.log(2, msg);
|
|
return;
|
|
}
|
|
zio_minus.put(riga_valenza);
|
|
riga_valenza.put(RMV_DESCR, TR("Minusvalenza"));
|
|
}
|
|
} //if(!imp_valenza.is_zero...
|
|
} //else di if(eliminazione...
|
|
|
|
//finalmente scrive sul file qesti movimenti...
|
|
int err = pn.write();
|
|
if (err != NOERR)
|
|
{
|
|
TString msg;
|
|
msg << TR("Impossibile registrare il movimento ") << numreg << "\n";
|
|
log.log(2, msg);
|
|
}
|
|
else
|
|
{
|
|
TString msg;
|
|
msg << TR("Registrato movimento ") << numreg << TR(" da movimento cespite ") << movce.get_long(MOVCE_IDMOV) << "\n";
|
|
log.log(0, msg);
|
|
}
|
|
|
|
} //for(int i=0;... (ciclo sui movimenti di un cespite)
|
|
}
|
|
|
|
|
|
//===============================================================================================
|
|
//Applicazione
|
|
|
|
class TTrasf_mov_ce_cg : public TSkeleton_application
|
|
{
|
|
TTrasf_mov_ce_cg_mask* _mask;
|
|
|
|
protected:
|
|
virtual void main_loop();
|
|
virtual bool create();
|
|
virtual bool destroy();
|
|
|
|
void elabora();
|
|
void genera_mov(TArray& righe_mov, const TDate& datareg, const TDate& datacomp,
|
|
const TString& codcaus, const int movdett, const bool definitivo, TLog_report& log);
|
|
void delete_old_movs(const TDate& ini_es);
|
|
|
|
public:
|
|
|
|
};
|
|
|
|
|
|
void TTrasf_mov_ce_cg::delete_old_movs(const TDate& ini_es)
|
|
{
|
|
TMovimentoPN_CE pn;
|
|
|
|
TRectype darec(LF_MOV);
|
|
darec.put(MOV_DATAREG, ini_es);
|
|
|
|
TString filtro;
|
|
filtro.format("(PROVVIS==\"C\")");
|
|
|
|
TCursor cur_mov (&pn, filtro, 2, &darec);
|
|
const long items = cur_mov.items();
|
|
cur_mov.freeze();
|
|
TProgind progind(items, "Eliminazione vecchi movimenti provvisori cespiti in corso...", false, true);
|
|
|
|
for (cur_mov = 0; cur_mov.pos() < items; ++cur_mov)
|
|
{
|
|
progind.addstatus(1);
|
|
pn.read();
|
|
pn.remove();
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//metodo per la generazione di movimenti con righe per categoria (chiamata se movdett=0)
|
|
void TTrasf_mov_ce_cg::genera_mov(TArray& righe_mov, const TDate& datareg, const TDate& datacomp, const TString& codcaus,
|
|
const int movdett, const bool definitivo, TLog_report& log)
|
|
{
|
|
//Riempie i campi della testata movimento
|
|
long numreg = get_new_numreg();
|
|
|
|
TMovimentoPN_CE pn;
|
|
TRectype& head = pn.curr();
|
|
|
|
fill_head(head, datacomp, datareg, numreg, codcaus, definitivo, "", "", NULLDATE);
|
|
head.put(MOV_DESCR, TR("Rilevazione quote amm. cespiti per categoria"));
|
|
|
|
//Procedura di inserimento delle righe del movimento
|
|
TImporto fondo;
|
|
//aggiunge all'array con tutte le righe mov determinate con il calcolo una riga senza gr/sp/cat
|
|
righe_mov.add(new TRigamov(0, EMPTY_STRING, 0));
|
|
//Ciclo su tutte le righe dell'array delle righe mov. Ad ogni cambio di categoria dovra' inserire la riga..
|
|
//..fondo per bilanciare la categoria, quindi scrivere sul movimento le righe ammortamento (da 1 a 3, ovvero..
|
|
//..qnor,qant,qacc) e la riga fondo di quella categoria, quindi passare alla categoria successiva.
|
|
for (int i = 0; i < righe_mov.items(); i++)
|
|
{
|
|
//record di righe_mov
|
|
const TRigamov& rigamov = (const TRigamov&)righe_mov[i];
|
|
|
|
//Controllo dell'eventuale cambio di categoria. Lo fa confrontando la riga iesima appena caricata con..
|
|
//..la riga i-1esima (la precedente,insomma)
|
|
//Se la categoria e' cambiata...
|
|
if (i > 0 && (rigamov.compare((const TRigamov&)righe_mov[i-1]) != 0 || pn.cg_items() > 95))
|
|
{
|
|
//crea una nuova riga per metterci il fondo;in questo momento la riga e' aggiunta ma va riempita!!
|
|
TRectype& riga_fondo = pn.nuova_riga();
|
|
|
|
//Inverte la sezione del fondo calcolato per il bilancamento
|
|
fondo.swap_section(); //inverte la sezione
|
|
fondo.normalize(); //normalizza il segno
|
|
riga_fondo.put(RMV_SEZIONE, fondo.sezione()); //inserisce nella riga fondo le sezione..
|
|
riga_fondo.put(RMV_IMPORTO, fondo.valore()); //..ed il valore
|
|
|
|
//Deve mettere nella riga fondo gr/co/sot che stanno nella categoria in CCC
|
|
//Serve la categoria precedente, perche' in questo momento l'ha cambiata! Quindi [i-1]
|
|
const TRigamov& prev_riga_mov = (const TRigamov&)righe_mov[i-1];
|
|
const TString& stringone = prev_riga_mov.categoria().get("S1");
|
|
riga_fondo.put(RMV_GRUPPO, stringone.mid(12,3));
|
|
riga_fondo.put(RMV_CONTO, stringone.mid(15,3));
|
|
riga_fondo.put(RMV_SOTTOCONTO, stringone.mid(18,6));
|
|
const TString descat = prev_riga_mov.descr_categoria();
|
|
riga_fondo.put(RMV_DESCR, descat);
|
|
|
|
//se il movimento supera le 95 righe va salvato sul file MOV, poi distrutto per poter costruirne uno nuovo..
|
|
//..con le righe di righe_mov che sono rimaste
|
|
if (pn.cg_items() > 95 || i == righe_mov.last() || movdett > 0)
|
|
{
|
|
if (movdett > 0) //se va per cespite la descrizione cambia per ogni movimento in base alla categoria
|
|
{
|
|
TString desc;
|
|
desc << TR("Quote amm. ") << descat;
|
|
desc.cut(50);
|
|
head.put(MOV_DESCR, desc);
|
|
}
|
|
|
|
int err = pn.write(); //scrive il movimento sul file
|
|
if (err != NOERR)
|
|
{
|
|
TString msg;
|
|
msg << TR("Impossibile registrare il movimento ") << numreg << "\n";
|
|
log.log(2, msg);
|
|
}
|
|
else
|
|
{
|
|
TString msg;
|
|
msg << TR("Registrato movimento ") << numreg << TR(" categoria ") << descat << "\n";
|
|
log.log(0, msg);
|
|
}
|
|
pn.destroy_rows(numreg); //ne elimina le righe per poter ricominciare
|
|
head.put(MOV_NUMREG, ++numreg); //nuova testata per nuovo movimento
|
|
}
|
|
|
|
//azzera il valore del fondo in modo da ricominciare a calcolarlo con la nuova categoria
|
|
fondo.reset();
|
|
} //if i>0&&rigamov.compare...
|
|
|
|
//Se la categoria non e' cambiata crea normalmente la nuova riga
|
|
//Aggiorna l'importo del fondo che e' pari alla somma di tutte le righe della stessa categoria
|
|
TImporto imp_riga(rigamov.get_char(RMV_SEZIONE), rigamov.get_real(RMV_IMPORTO));
|
|
fondo += imp_riga;
|
|
pn.nuova_riga(rigamov);
|
|
} //for(inti=0;...
|
|
|
|
}
|
|
|
|
|
|
//metodo per gestire la successione degli eventi ad alto livello
|
|
void TTrasf_mov_ce_cg::elabora()
|
|
{
|
|
//gettiamo un po' di parametri dalla maschera
|
|
const long codes = _mask->get_long(F_ESERCIZIO);
|
|
const TDate ini_es = _mask->get_date(F_INIZIO_ES);
|
|
const TDate fine_es = _mask->get_date(F_FINE_ES);
|
|
//deve accoppare i movimenti provvisori di prima nota da inizio esercizio ad oggi?
|
|
if (_mask->get_bool(F_KILLOLD))
|
|
delete_old_movs(ini_es);
|
|
|
|
//ragionamenti sulle date
|
|
const TDate datareg = _mask->get_date(F_DATAREG);
|
|
const TDate datacomp = min(fine_es, datareg);
|
|
//se il trasferimento e' definitivo la data di calcolo e' quella finale dell'esercizio selezionato, senno'...
|
|
//...e' quella indicata in F_DATACALC
|
|
TDate datacalc;
|
|
const bool definitivo = _mask->get_bool(F_PROVDEF);
|
|
if (definitivo)
|
|
datacalc = _mask->get_date(F_FINE_ES);
|
|
else
|
|
datacalc = _mask->get_date(F_DATACALC);
|
|
|
|
//report con log errori
|
|
TLog_report cont_cesp_log(TR("Contabilizzazione cespiti"));
|
|
cont_cesp_log.kill_duplicates();
|
|
|
|
//Legge un po' di parametri dal ditta.ini che servono al tipo di calcolo
|
|
TConfig config_ditta_ce(CONFIG_DITTA, "ce");
|
|
//Situazione fiscale (99,99%) o civilistica (1 suora su 1.000.000)?
|
|
const int tpamm = config_ditta_ce.get_int("TPAMM");
|
|
//Tipo di calcolo da eseguire in base al dettaglio
|
|
const int movdett = config_ditta_ce.get_int("MOVDETT");
|
|
//Codice causale da mettere nei movimenti generati
|
|
const TString4 codcaus = config_ditta_ce.get("COAUQU");
|
|
//Genera movimenti plus/minus? Parametro decisivo per poter generare movimenti cg da movimenti ce
|
|
const bool mov_plusmin = config_ditta_ce.get_bool("COPLMN");
|
|
|
|
//**********************************************************************************
|
|
// 1) Generazione movimenti CG da ammortamenti
|
|
//**********************************************************************************
|
|
//programma vero e proprio (calcolo ammortamenti, selezione cespiti validi, trasferimento)
|
|
TISAM_recordset cespiti("USE CESPI");
|
|
const TRecnotype nrec = cespiti.items();
|
|
|
|
//Assoc_array Categoria-QammTot
|
|
TAssoc_array quote_per_codice;
|
|
TArray ammo_plus_minus;
|
|
|
|
TProgind pi(nrec, TR("Ricalcolo ammortamenti in corso..."), true, true);
|
|
for (int i = 0; cespiti.move_to(i); i++)
|
|
{
|
|
if (!pi.addstatus(1))
|
|
break;
|
|
//id e categoria del cespite corrente
|
|
const TString& idcespite = cespiti.get(CESPI_IDCESPITE).as_string();
|
|
const int gruppo = cespiti.get(CESPI_CODCGRA).as_int();
|
|
const TString4 specie = cespiti.get(CESPI_CODSPA).as_string();
|
|
const int codcat = cespiti.get(CESPI_CODCAT).as_int();
|
|
|
|
//calcola gli ammortamenti di tutti i cespiti; situazione presa dal config_ditta poco prima
|
|
//la calc_amm pensa da sola a calcolare gli ammortamenti solo per i cespiti validi
|
|
//l'ultimo parametro e' true x' il calcolo viene fatto in memoria!
|
|
TCespite cespite(idcespite);
|
|
|
|
if (cespite.calc_amm(tpamm, datacalc, false, true))
|
|
{
|
|
//controlla le quote del cespite in questione su AMMCE
|
|
const TRectype& rec_ammce = cespite.amm_pro();
|
|
|
|
//in base al tipo di dettaglio sceglie il codice dell'assoc_array
|
|
//movdett=0 -> codice=codice categoria (assoc_array con record per categorie)
|
|
//movdett=1;2 -> codice=idcespite (assoc_array con record per cespite)
|
|
TToken_string gsc;
|
|
gsc.add(gruppo); gsc.add(specie); gsc.add(codcat);
|
|
if (movdett != 0)
|
|
gsc.add(idcespite);
|
|
|
|
TSaldo_per_codice* sc = (TSaldo_per_codice*)quote_per_codice.objptr(gsc);
|
|
//se non trova il codice (categoria o cespite) lo aggiunge...
|
|
if (sc == NULL)
|
|
{
|
|
sc = new TSaldo_per_codice(gruppo, specie, codcat, idcespite);
|
|
quote_per_codice.add(gsc, sc);
|
|
}
|
|
//..e poi somma i valori comunque
|
|
sc->add(rec_ammce);
|
|
|
|
//Parte relativa ad AMMMV (per generazione movimenti cg da movim. cespiti)
|
|
if (mov_plusmin)
|
|
{
|
|
const TArray& ammmv = cespite.ammmv();
|
|
const TArray& movam = cespite.movam();
|
|
const TArray& movce = cespite.movce();
|
|
|
|
TPlus_minus* pm = new TPlus_minus(gruppo, specie, codcat, ammmv, movam, movce);
|
|
ammo_plus_minus.add(pm);
|
|
|
|
}
|
|
|
|
}
|
|
} //for(int i...
|
|
|
|
TArray saldi_ordinati;
|
|
//riempie l'array saldi_ordinati con gli elementi dell'assoc quote_per_codice
|
|
FOR_EACH_ASSOC_OBJECT(quote_per_codice, h, k, obj)
|
|
saldi_ordinati.add(h->remove_obj());
|
|
//accoppa l'assoc
|
|
quote_per_codice.destroy();
|
|
//e ordina l'array per categorie e cespite (questo assurdo giro serve perche' l'assoc non e' ordinabile)
|
|
saldi_ordinati.sort();
|
|
|
|
//array con le righe movimento CG
|
|
TArray righe_mov;
|
|
//riempie l'array delle righe movimento CG
|
|
FOR_EACH_ARRAY_ITEM(saldi_ordinati, riga, sldobj)
|
|
{
|
|
const TSaldo_per_codice& sld = *(const TSaldo_per_codice*)sldobj;
|
|
sld.genera_righe(righe_mov, cont_cesp_log, movdett);
|
|
}
|
|
|
|
//controllo sul numero righe dell'array (serve solo per controllo al sagace programmatore...)
|
|
const int nrighemov = righe_mov.items();
|
|
|
|
//a questo punto ha l'array con le righe movimento CG completo (righe_mov); da queste righe deve costruire..
|
|
//..uno o piu' movimenti di prima nota
|
|
//In base al movdett li creera' con righe per categoria o per cespite ma con fondi per categoria
|
|
//E' un metodo semimagico!
|
|
genera_mov(righe_mov, datareg, datacomp, codcaus, movdett, definitivo, cont_cesp_log);
|
|
|
|
//**********************************************************************************
|
|
// 2) Generazione movimenti CG da movimenti cespiti di vendita/eliminazione
|
|
//**********************************************************************************
|
|
//solo se in configurazione ditta cespiti e' attivo il flag di generazione movimenti plus/minus...
|
|
if (mov_plusmin)
|
|
{
|
|
//controllo sul numero righe dell'array (serve solo per controllo al sagace programmatore...)
|
|
const int nrigheammo = ammo_plus_minus.items();
|
|
|
|
//scandisce l'array con i valori per i movimenti di plus/minus creando un movimento cg per ognuno
|
|
FOR_EACH_ARRAY_ITEM(ammo_plus_minus, riga, pmobj)
|
|
{
|
|
const TPlus_minus& pm = *(const TPlus_minus*)pmobj;
|
|
pm.genera_mov_elim_ven(config_ditta_ce, datacomp, datareg, definitivo, cont_cesp_log);
|
|
}
|
|
}
|
|
|
|
//***************************************
|
|
// 3) stampa il log degli errori
|
|
//***************************************
|
|
TReport_book book;
|
|
book.add(cont_cesp_log);
|
|
book.preview();
|
|
|
|
}
|
|
|
|
bool TTrasf_mov_ce_cg::create()
|
|
{
|
|
_mask = new TTrasf_mov_ce_cg_mask;
|
|
return TSkeleton_application::create();
|
|
}
|
|
|
|
bool TTrasf_mov_ce_cg::destroy()
|
|
{
|
|
delete _mask;
|
|
return true;
|
|
}
|
|
|
|
void TTrasf_mov_ce_cg::main_loop()
|
|
{
|
|
KEY k = K_ENTER;
|
|
while (k != K_QUIT)
|
|
{
|
|
k = _mask->run();
|
|
|
|
switch (k)
|
|
{
|
|
case K_ENTER:
|
|
elabora();
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
int ce4400(int argc, char* argv[])
|
|
{
|
|
TTrasf_mov_ce_cg a;
|
|
a.run(argc,argv,TR("Trasferimento cespiti in contabilita'"));
|
|
return 0;
|
|
}
|