4885 lines
157 KiB
C++
Executable File
4885 lines
157 KiB
C++
Executable File
#include "velib04.h"
|
||
#include "../ca/calib01.h"
|
||
#include "../cg/cg2103.h"
|
||
#include "../cg/cglib02.h"
|
||
#include "../cg/cgsaldac.h"
|
||
#include "../in/inlib01.h"
|
||
|
||
#include <dongle.h>
|
||
#include <execp.h>
|
||
#include <postman.h>
|
||
#include <printer.h>
|
||
#include <viswin.h>
|
||
#include <utility.h>
|
||
|
||
#include <comuni.h>
|
||
#include <unloc.h>
|
||
#include "../ca/movana.h"
|
||
#include "../m770/scperc.h"
|
||
#include "../m770/rver.h"
|
||
#include "../m770/perc.h"
|
||
|
||
|
||
void TMovimentoPN_VE::destroy_iva_row(int i)
|
||
{
|
||
if (i < 0)
|
||
iva_rows().destroy_rows();
|
||
else
|
||
iva_rows().destroy_row(i+1, true);
|
||
}
|
||
|
||
TImporto TMovimentoPN_VE::real2imp(const real& r, char row_type)
|
||
{
|
||
bool dare = false;
|
||
if (row_type == 'S')
|
||
dare = _caus->sezione_ritsoc() == 'D'; else
|
||
if (row_type == 'V')
|
||
dare = _caus->sezione_revcharge() == 'D'; else
|
||
if (row_type == 'F')
|
||
dare = _caus->sezione_ritfis() == 'D';
|
||
else
|
||
{
|
||
dare = _caus->sezione_clifo() == 'D';
|
||
if (row_type != 'T' && row_type != 'F' && row_type != 'P')
|
||
dare = !dare;
|
||
}
|
||
|
||
TImporto importo(dare ? 'D' : 'A', r);
|
||
return importo;
|
||
}
|
||
|
||
int TMovimentoPN_VE::bill2pos(const TBill& conto, char tipo)
|
||
{
|
||
const int items = cg_items();
|
||
for (int i = 0; i < items; i++)
|
||
{
|
||
const TRectype& s = cg(i);
|
||
const char t = s.get_char(RMV_ROWTYPE);
|
||
if (t == tipo)
|
||
{
|
||
const TBill c(s);
|
||
if (c == conto)
|
||
return i;
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
int TMovimentoPN_VE::type2pos(char tipo)
|
||
{
|
||
const int items = cg_items();
|
||
for (int i = 0; i < items; i++)
|
||
{
|
||
const TRectype& s = cg(i);
|
||
const char t = s.get_char(RMV_ROWTYPE);
|
||
if (t == tipo)
|
||
return i;
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
void TMovimentoPN_VE::set_cg_imp(int n, const TImporto& imp)
|
||
{
|
||
TRectype& rec = cg(n);
|
||
rec.put(RMV_SEZIONE,imp.sezione());
|
||
rec.put(RMV_IMPORTO,imp.valore());
|
||
}
|
||
|
||
TImporto TMovimentoPN_VE::get_cg_imp(int n)
|
||
{
|
||
const TRectype& rec = cg(n);
|
||
const TImporto importo(rec.get_char(RMV_SEZIONE), rec.get_real(RMV_IMPORTO));
|
||
return importo;
|
||
}
|
||
|
||
bool TMovimentoPN_VE::add_cg_rec(int n, const TImporto& imp)
|
||
{
|
||
TImporto tot(get_cg_imp(n));
|
||
tot += imp;
|
||
tot.normalize();
|
||
set_cg_imp(n, tot);
|
||
return tot.is_zero();
|
||
}
|
||
|
||
int TMovimentoPN_VE::set_cg_rec(int n, const TImporto& imp, const TBill& conto, const char* desc, char tipo)
|
||
{
|
||
const bool insert = n < 0;
|
||
if (insert) n = cg_items(); // Questa <20> la prima riga di contabilita' vuota e disponibile
|
||
TRectype& rec = cg(n);
|
||
|
||
if (insert)
|
||
{
|
||
TRectype& head = curr();
|
||
const int annoes = head.get_int(MOV_ANNOES);
|
||
const long numreg = head.get_long(MOV_NUMREG);
|
||
TDate datareg(head.get_date(MOV_DATAREG));
|
||
rec.put(RMV_ANNOES,annoes);
|
||
rec.put(RMV_NUMREG,numreg);
|
||
rec.put(RMV_DATAREG,datareg);
|
||
}
|
||
|
||
TImporto normimp(imp);
|
||
normimp.normalize();
|
||
rec.put(RMV_SEZIONE,normimp.sezione());
|
||
rec.put(RMV_IMPORTO,normimp.valore());
|
||
conto.put(rec);
|
||
|
||
rec.put(RMV_DESCR, desc);
|
||
|
||
if (tipo != ' ')
|
||
{
|
||
if (tipo == 'T') // Calcolo contropartita
|
||
{
|
||
const TBill zio(iva(0));
|
||
zio.put(rec, true);
|
||
}
|
||
else
|
||
{
|
||
int pos = -1;
|
||
if (tipo == 'F' || tipo == '2')
|
||
{
|
||
pos = type2pos('D');
|
||
if (pos == -1)
|
||
pos = type2pos('N');
|
||
}
|
||
else
|
||
pos = type2pos('T');
|
||
if (pos >= 0)
|
||
{
|
||
const TBill zio(cg(pos));
|
||
zio.put(rec, true);
|
||
}
|
||
}
|
||
}
|
||
|
||
rec.put(RMV_ROWTYPE,tipo);
|
||
return n;
|
||
}
|
||
|
||
int TMovimentoPN_VE::insert_cg_rec(int n, const TImporto& imp, TBill& conto,
|
||
const char* desc, char tipo)
|
||
{
|
||
if (n >= 0 && n < cg_items())
|
||
{
|
||
TRectype * row = new TRectype(LF_RMOV);
|
||
TRectype& head = lfile().curr();
|
||
const int annoes = head.get_int(MOV_ANNOES);
|
||
const long numreg = head.get_long(MOV_NUMREG);
|
||
TDate datareg(head.get_date(MOV_DATAREG));
|
||
|
||
row->put(RMV_NUMREG,numreg);
|
||
row->put(RMV_NUMRIG, n + 1);
|
||
row->put(RMV_ANNOES,annoes);
|
||
row->put(RMV_DATAREG,datareg);
|
||
cg_rows().insert_row(row);
|
||
}
|
||
return set_cg_rec(n, imp, conto, desc, tipo);
|
||
}
|
||
|
||
void TMovimentoPN_VE::enter_row(int i, const TString& descr_cr)
|
||
{
|
||
CHECK(_caus,"Orgggssbb..._caus pointer is NULL!");
|
||
|
||
TRectype& cur = iva(i);
|
||
const TString4 tipodet = cur.get(RMI_TIPODET);
|
||
const TString4 zanicchi = cur.get(RMI_CODIVA); // Codice IVA
|
||
real imponibile = cur.get_real(RMI_IMPONIBILE);
|
||
real imposta = cur.get_real(RMI_IMPOSTA);
|
||
|
||
if (imposta.is_zero() && _caus->corrispettivi()) // In caso di corrispettivi ...
|
||
{
|
||
const TCodiceIVA i(zanicchi);
|
||
imposta = i.scorpora(imponibile); // ... scorpora imposta dall'imponibile
|
||
}
|
||
|
||
// Calcola riga causale col conto opportuno
|
||
const int anno = curr().get_date(MOV_DATAREG).year();
|
||
real imp, impind, iva, ivaind;
|
||
int flag = analizza_riga_IVA(imponibile, imposta, *_caus, anno, zanicchi, tipodet, imp, iva, impind, ivaind);
|
||
const TBill conto(cur);
|
||
|
||
imponibile = imp + impind;
|
||
if (conto.ok() && !imponibile.is_zero()) // Se c'<27> imponibile ...
|
||
{ // crea una nuova riga contabile
|
||
// Aggiorna conto sulla riga contabile
|
||
const TImporto val(real2imp(imponibile, 'I'));
|
||
const int newpos = bill2pos(conto, 'I'); // Riga in cui andr<64> l'imponibile
|
||
|
||
if (newpos < 0) // conto non esistente: da inserire
|
||
{
|
||
const TFixed_string d = _caus->desc_agg(2);
|
||
set_cg_rec(-1, val, conto, d.empty() ? descr_cr : d, 'I');
|
||
}
|
||
else
|
||
add_cg_rec(newpos, val);
|
||
cur.put(RMI_RIGAIMP, newpos+1); // Aggiorna riferimento alla riga contabile
|
||
}
|
||
|
||
// Aggiorna conto IVA sulla riga contabile
|
||
if (!iva.is_zero()) // Se c'<27> imposta ...
|
||
{
|
||
const TRectype& head = lfile().curr();
|
||
int newposiva = type2pos('D'); // IVA detraibile
|
||
TImporto val(real2imp(iva, 'I'));
|
||
|
||
if (newposiva < 0)
|
||
{
|
||
int ri = RIGA_IVA_DETRAIBILE;
|
||
TBill contoiva;
|
||
if (head.get_bool(MOV_LIQDIFF))
|
||
_caus->bill(ri = RIGA_IVA_DIFFERITA, contoiva); else
|
||
if (head.get_bool(MOV_IVAXCASSA))
|
||
_caus->bill(ri = RIGA_IVA_PER_CASSA, contoiva);
|
||
if (!contoiva.ok())
|
||
_caus->bill(ri = RIGA_IVA_DETRAIBILE, contoiva);
|
||
if (contoiva.ok())
|
||
{
|
||
const TString80 d = _caus->desc_agg(ri);
|
||
newposiva = set_cg_rec(-1, val, contoiva, d, 'D');
|
||
}
|
||
}
|
||
else
|
||
add_cg_rec(newposiva, val);
|
||
|
||
if (is_split_payment(head))
|
||
{
|
||
const char* desc = TR("IVA art.17-ter D.P.R. 633/1972");
|
||
|
||
const int r1 = type2pos('1');
|
||
if (r1 < 0)
|
||
{
|
||
const TBill cliente(cg(0));
|
||
set_cg_rec(r1, val, cliente, desc, '1');
|
||
}
|
||
else
|
||
add_cg_rec(r1, val);
|
||
|
||
val.swap_section();
|
||
const int r2 = type2pos('2');
|
||
if (r2 < 0)
|
||
{
|
||
const TBill contoiva(cg(newposiva));
|
||
set_cg_rec(r2, val, contoiva, desc, '2');
|
||
}
|
||
else
|
||
add_cg_rec(r2, val);
|
||
}
|
||
}
|
||
|
||
if (!ivaind.is_zero()) // Se c'<27> IVA indetraibile ...
|
||
{
|
||
int newposiva = type2pos('N');
|
||
const TImporto val(real2imp(ivaind, 'I'));
|
||
if (newposiva < 0)
|
||
{
|
||
const TString80 desc = _caus->desc_agg(RIGA_IVA_NON_DETRAIBILE);
|
||
TBill contoivaind;
|
||
_caus->bill(RIGA_IVA_NON_DETRAIBILE, contoivaind);
|
||
if (contoivaind.ok())
|
||
newposiva = set_cg_rec(-1, val, contoivaind, desc, 'N');
|
||
}
|
||
else
|
||
add_cg_rec(newposiva, val);
|
||
}
|
||
}
|
||
|
||
void TMovimentoPN_VE::add_row_re(int i)
|
||
{
|
||
TRectype& cur = iva(i);
|
||
real imponibile = cur.get_real(RMI_IMPONIBILE);
|
||
real imposta = cur.get_real(RMI_IMPOSTA);
|
||
const int anno = lfile().curr().get_date(MOV_DATAREG).year();
|
||
const TString4 tipodet = cur.get(RMI_TIPODET);
|
||
const TString4 zanicchi(cur.get(RMI_CODIVA)); // Codice IVA
|
||
real imp, impind, iva, ivaind;
|
||
|
||
analizza_riga_IVA(imponibile, imposta, *_caus, anno, zanicchi, tipodet, imp, iva, impind, ivaind);
|
||
imponibile = imp + impind;
|
||
if (!ivaind.is_zero())
|
||
{
|
||
TBill contoivaind;
|
||
|
||
_caus->bill(RIGA_IVA_NON_DETRAIBILE, contoivaind);
|
||
const TImporto val(real2imp(ivaind, 'I'));
|
||
int ivapos = bill2pos(contoivaind, 'I');
|
||
|
||
if (ivapos < 0)
|
||
set_cg_rec(-1, val, contoivaind, "", 'I');
|
||
else
|
||
add_cg_rec(ivapos, val);
|
||
}
|
||
|
||
const TBill conto(cur);
|
||
int newpos = bill2pos(conto, ' '); // Riga in cui andra' l'imponibile
|
||
|
||
if (conto.ok() && !imponibile.is_zero())
|
||
{
|
||
const TImporto val(real2imp(imponibile, 'I'));
|
||
if (newpos < 0)
|
||
set_cg_rec(-1, val, conto, _caus->desc_agg(2), ' ');
|
||
else
|
||
add_cg_rec(newpos, val);
|
||
}
|
||
}
|
||
|
||
void TMovimentoPN_VE::add_row_tot_re(TDocumento& doc)
|
||
{
|
||
TBill c;
|
||
TImporto imp = real2imp(doc.imponibile(), 'T');
|
||
|
||
_caus->bill(1, c);
|
||
if (c.tipo() > ' ')
|
||
c.set(c.gruppo(), c.conto(), curr().get_long(MOV_CODCF), c.tipo());
|
||
imp.normalize();
|
||
|
||
insert_cg_rec(0, imp, c, _caus->desc_agg(1), ' ');
|
||
}
|
||
|
||
bool TMovimentoPN_VE::add_row_cp_re(int i)
|
||
{
|
||
bool inserted_row = false;
|
||
|
||
const TRectype& cur = cg(i);
|
||
TBill c(cur); map_conto_re(c);
|
||
if (c.ok())
|
||
{
|
||
int poscg = bill2pos(c, ' ');
|
||
if (poscg < 0)
|
||
{
|
||
poscg = insert_cg_rec(0, real2imp(ZERO, 'P'), c, _caus->desc_agg(1), ' ');
|
||
inserted_row = true;
|
||
}
|
||
TImporto val(real2imp(cur.get_real(RMV_IMPORTO), 'P'));
|
||
|
||
add_cg_rec(poscg, val);
|
||
}
|
||
|
||
return inserted_row;
|
||
}
|
||
|
||
void TMovimentoPN_VE::map_conto_re(TBill& c)
|
||
{
|
||
TString16 key;
|
||
|
||
key.format("%3d%3d%6ld",c.gruppo(), c.conto(), c.sottoconto());
|
||
const TRectype* rs = &cache().get("&MRE", key);
|
||
if (rs->empty())
|
||
{
|
||
key.cut(6);
|
||
rs = &cache().get("&MRE", key);
|
||
if (rs->empty())
|
||
{
|
||
key.cut(3);
|
||
rs = &cache().get("&MRE", key);
|
||
}
|
||
}
|
||
|
||
if (rs->empty())
|
||
_caus->bill(1, c);
|
||
else
|
||
{
|
||
const int gr = rs->get_int("I0");
|
||
const int co = rs->get_int("I1");
|
||
const long so = rs->get_int("I2");
|
||
const char tipo = rs->get_char("S6");
|
||
c.set(gr, co, so, tipo);
|
||
}
|
||
if (c.tipo() > ' ')
|
||
c.set(c.gruppo(), c.conto(), curr().get_long(MOV_CODCF), c.tipo());
|
||
}
|
||
|
||
bool TMovimentoPN_VE::movement_ok()
|
||
{
|
||
TImporto tot_imp;
|
||
TImporto imp;
|
||
|
||
// Se siamo in valuta, forzer<65> la riga totale documento a ci<63> che si ottiene dalla somma
|
||
// delle singole righe per evitare sbilanci nel movimento di 2,3,4,5 lire dovuti agli arrotondamenti
|
||
const int max = cg_items();
|
||
for (int i = 0; i < max; i++)
|
||
{
|
||
if (i == 0 && _valuta)
|
||
continue;
|
||
TRectype& r = cg(i);
|
||
const char sez = r.get_char(RMV_SEZIONE);
|
||
const real val(r.get_real(RMV_IMPORTO));
|
||
imp.set(sez,val);
|
||
tot_imp+=imp;
|
||
}
|
||
|
||
if (_valuta) //documento in valuta
|
||
{
|
||
TRectype& r = cg(0);
|
||
// Setta la riga di totale documento...
|
||
r.put(RMV_IMPORTO,tot_imp.valore());
|
||
r.put(RMV_SEZIONE,tot_imp.sezione() == 'D' ? 'A' : 'D'); // Sezione contraria
|
||
// ...ed anche il totale documento sulla testata
|
||
lfile().curr().put(MOV_TOTDOC,tot_imp.valore());
|
||
tot_imp.valore() = 0.0;
|
||
if (_caus != NULL && _caus->intra())
|
||
{
|
||
const TString& totdoc = curr().get(MOV_TOTDOC);
|
||
curr().put(MOV_CORRLIRE, totdoc);
|
||
}
|
||
}
|
||
else //documento senza valuta; nel campo CODVALI ci va il codice valuta della ditta bug368
|
||
{
|
||
TString4 codval_ditta = TCurrency::get_firm_val();
|
||
curr().put(MOV_CODVALI, codval_ditta);
|
||
}
|
||
|
||
if (!tot_imp.is_zero())
|
||
return false;
|
||
return true;
|
||
}
|
||
|
||
int TMovimentoPN_VE::recalc_cg_rows(const TString& descr_cr, TCausale& caus)
|
||
{
|
||
const int righe_IVA = iva_items();
|
||
const TRectype& head = curr();
|
||
|
||
set_caus(&caus);
|
||
for (int i=0; i < righe_IVA; i++)
|
||
enter_row(i, descr_cr);
|
||
|
||
bool ok = true;
|
||
if (_caus->intra() && _caus->iva() == iva_acquisti)
|
||
{
|
||
TBill c; _caus->bill(RIGA_RITENUTE_FISCALI, c);
|
||
ok = c.ok();
|
||
if (ok)
|
||
{
|
||
const TString80 d = _caus->desc_agg(RIGA_RITENUTE_FISCALI);
|
||
const char rowtype = 'F';
|
||
set_cg_rec(-1, real2imp(head.get_real(MOV_RITFIS), rowtype), c, d, rowtype);
|
||
}
|
||
else
|
||
return 2;
|
||
}
|
||
else
|
||
{
|
||
const real ritfis = head.get_real(MOV_RITFIS);
|
||
if (!ritfis.is_zero())
|
||
{
|
||
TBill c; _caus->bill(RIGA_RITENUTE_FISCALI, c);
|
||
ok = c.ok();
|
||
if (ok)
|
||
{
|
||
const TString80 d = _caus->desc_agg(RIGA_RITENUTE_FISCALI);
|
||
const char rowtype = 'F';
|
||
set_cg_rec(-1, real2imp(ritfis, rowtype), c, d, rowtype);
|
||
}
|
||
else
|
||
return 1;
|
||
}
|
||
|
||
const real ritsoc = head.get_real(MOV_RITSOC);
|
||
if (!ritsoc.is_zero())
|
||
{
|
||
TBill c; _caus->bill(RIGA_RITENUTE_SOCIALI, c);
|
||
ok = c.ok();
|
||
if (ok)
|
||
{
|
||
const TString80 d = _caus->desc_agg(RIGA_RITENUTE_SOCIALI);
|
||
const char rowtype = 'S';
|
||
set_cg_rec(-1, real2imp(ritsoc, rowtype), c, d, rowtype);
|
||
}
|
||
else
|
||
return 1;
|
||
}
|
||
|
||
const real revchg = head.get_real(MOV_REVCHARGE);
|
||
if (!revchg.is_zero())
|
||
{
|
||
TBill c; _caus->bill(RIGA_REVERSE_CHARGE, c);
|
||
ok = c.ok();
|
||
if (ok)
|
||
{
|
||
const TString80 d = _caus->desc_agg(RIGA_REVERSE_CHARGE);
|
||
const char rowtype = 'V';
|
||
set_cg_rec(-1, real2imp(revchg, rowtype), c, d, rowtype);
|
||
}
|
||
else
|
||
return 1;
|
||
}
|
||
|
||
}
|
||
|
||
if (_caus->tipomov() == tm_fattura) // Elimina eventuali righe vuote dalle fatture
|
||
{
|
||
const bool is_zero_doc = (righe_IVA > 0) && head.get_real(MOV_TOTDOC).is_zero();
|
||
for (int c = cg_items()-1; c >= 0; c--)
|
||
{
|
||
const TImporto imp = get_cg_imp(c);
|
||
bool can_delete = imp.is_zero();
|
||
if (can_delete && is_zero_doc)
|
||
{
|
||
const TRectype& s = cg(c);
|
||
can_delete = s.get_char(RMV_ROWTYPE) != 'T';
|
||
}
|
||
if (can_delete)
|
||
destroy_cg_row(c);
|
||
}
|
||
}
|
||
|
||
return ok && movement_ok() ? 0 : 1;
|
||
}
|
||
|
||
// Parametri da leggere all'inizio dell'elaborazione tramite load_parameters()
|
||
static TBill _sco_perc_bill, _sco_imp_bill; // Conti per gli sconti a percentuale ed importi (dalla configurazione)
|
||
static TBill _spin_billa, _spin_billv,
|
||
_spbo_billa, _spbo_billv;
|
||
static TBill _co_cliente, // conto clifo per movimento d'anticipo
|
||
_co_controp; // conto di contropartita per il movimetno d'anticipo
|
||
|
||
static bool _nump_cfg; // se true prende il numero rif. partita dal numero protocollo
|
||
static bool _sc_enabled; // se true il saldaconto di ditta <20> abilitato
|
||
static bool _in_enabled; // se true l'intra <20> abilitato
|
||
static TToken_string* _search_seq = NULL;
|
||
// Sequenza di ricerca del conto costo/ricavo la correttezza dell'ordinamento
|
||
// va controllata nel programma di modifica parametri:
|
||
// "" = fine ordinamento
|
||
// CF = cliente fornitore
|
||
// CA = causale
|
||
// AR = articolo (costo/ricavo)
|
||
// GM = gruppo merceologico
|
||
// SM = sottogruppo merceologico
|
||
// RF = raggruppamento fiscale
|
||
// CV = categoria di vendita
|
||
// CC = categoria contabile
|
||
// Gli utlimi 6 fanno parte della ricerca per costi ricavi, in particolare AR,GM,SM e RF
|
||
// non possono essere interrotti da CV o CC. Ad es. CA|CF|AR|CV|GM|CC|RF non <20> valida come stringa
|
||
// di ricerca.
|
||
static TString4 _iva_sto; // Codice IVA per storno articoli Omaggio
|
||
static TBill _conto_sto; // Conto per storno articoli Omaggio
|
||
static bool _contsclor; // Contabilizza sconti al netto o al lordo (sconti suddiviso per ogni contropartita)
|
||
//static bool _loaded = false;// Flag per evitare di caricare i parametri pi<70> di una volta
|
||
|
||
static TCausale *_caus = NULL; // causale del documento corrente
|
||
static TMovimentoPN_VE *_movimento = NULL; // Movimento di prima nota documento vendita
|
||
static TMovimentoPN *_anticipo = NULL; // Movimento di prima nota relativamente all'anticipo indicato sul documento
|
||
|
||
class TIVA_array : public TAssoc_array
|
||
{
|
||
TCausale* _caus; // causale del documento corrente
|
||
|
||
protected:
|
||
void copy(const TIVA_array& a);
|
||
TObject* dup() const { return new TIVA_array(*this); }
|
||
|
||
public:
|
||
error_type add(const TRiga_documento& r, const TBill& conto, const int ndec = ALL_DECIMALS, const real & p = UNO);
|
||
//error_type add(const TRiga_documento* r, const TBill& conto, const int ndec = ALL_DECIMALS, const real & p = UNO) { return add(*r, conto, ndec, p);}
|
||
error_type add_omaggi(const TRiga_documento& r, const TBill& conto, const int ndec = ALL_DECIMALS, const real & p = UNO);
|
||
//error_type add_omaggi(const TRiga_documento* r, const TBill& conto, const int ndec = ALL_DECIMALS, const real & p = UNO) { return add_omaggi(*r, conto, ndec, p);}
|
||
void set_caus(TCausale * caus) { _caus = caus; }
|
||
|
||
TIVA_array() {}
|
||
// @cmember Costruttore. Copia tutto l'array associativo e ne duplica gli elementi
|
||
TIVA_array(const TIVA_array& a) { copy(a); }
|
||
virtual ~TIVA_array() {}
|
||
};
|
||
|
||
void TIVA_array::copy(const TIVA_array & a)
|
||
{
|
||
TAssoc_array::copy(a);
|
||
_caus = a._caus;
|
||
}
|
||
|
||
error_type TIVA_array::add_omaggi(const TRiga_documento& r, const TBill& conto, const int ndec, const real& p)
|
||
{
|
||
if (_iva_sto.blank())
|
||
return ivasto_error;
|
||
add(r, conto, ndec, p);
|
||
TRiga_documento r_storno(r);
|
||
|
||
r_storno.set_tipo("01"); // Riga merce standard
|
||
r_storno.put(RDOC_CODIVA, _iva_sto);
|
||
const real prezzo = -r_storno.get_real(RDOC_PREZZO);
|
||
|
||
r_storno.put(RDOC_PREZZO, prezzo);
|
||
|
||
if (_conto_sto.ok())
|
||
add(r_storno, _conto_sto, ndec, p);
|
||
else
|
||
add(r_storno, conto, ndec, p);
|
||
|
||
return no_error;
|
||
}
|
||
|
||
error_type TIVA_array::add(const TRiga_documento& r, const TBill& conto, const int ndec, const real& p)
|
||
{
|
||
const TTipo_riga_documento & t = r.tipo();
|
||
const TCodiceIVA& tiva = r.iva();
|
||
const TString4 cod = tiva.codice();
|
||
TBill c(conto);
|
||
int ord = 0;
|
||
int detr = 0;
|
||
real impon;
|
||
const bool sconto_lordo = t.tipo() != RIGA_SCONTI && _contsclor && _sco_perc_bill.ok();
|
||
const int firmdec = TCurrency::get_firm_dec();
|
||
|
||
const TRectype * rdoc = r.find_original_rdoc();
|
||
|
||
if (rdoc != NULL && rdoc->get(RDOC_PROVV).not_empty())
|
||
{
|
||
TString80 key = rdoc->get(RDOC_CODNUM);
|
||
|
||
const TCodice_numerazione& num = cached_numerazione(key);
|
||
if (num.fattura_emettere_ricevere())
|
||
{
|
||
key.format("%3d%3d%6ld", c.gruppo(), c.conto(), c.sottoconto());
|
||
const TRectype* rs = &cache().get("&MRE", key);
|
||
if (rs->empty())
|
||
{
|
||
key.cut(6);
|
||
rs = &cache().get("&MRE", key);
|
||
if (rs->empty())
|
||
{
|
||
key.cut(3);
|
||
rs = &cache().get("&MRE", key);
|
||
}
|
||
}
|
||
if (rs->empty())
|
||
{
|
||
key = rdoc->get(RDOC_PROVV);
|
||
key << '|' << rdoc->get(RDOC_ANNO);
|
||
key << '|' << rdoc->get(RDOC_CODNUM);
|
||
key << '|' << rdoc->get(RDOC_NDOC);
|
||
|
||
const TRectype & doc = cache().get(LF_DOC, key);
|
||
const TTipo_documento& td = cached_tipodoc(doc.get(DOC_TIPODOC));
|
||
const TString& codcau = td.causale();
|
||
const TCausale caus(codcau);
|
||
|
||
caus.bill(1, c);
|
||
}
|
||
else
|
||
{
|
||
const int gr = rs->get_int("I0");
|
||
const int co = rs->get_int("I1");
|
||
const long so = rs->get_int("I2");
|
||
const char tipo = rs->get_char("S6");
|
||
|
||
c.set(gr, co, so, tipo);
|
||
}
|
||
if (c.tipo() > ' ')
|
||
c.set(c.gruppo(), c.conto(), r.doc().get_long(DOC_CODCF), c.tipo());
|
||
}
|
||
}
|
||
if (!sconto_lordo) // Al netto dello sconto
|
||
impon = r.imponibile();
|
||
else
|
||
impon = r.importo(false,false,ndec); // Imponibile della riga al lordo dello sconto
|
||
|
||
switch (t.tipo())
|
||
{
|
||
case RIGA_MERCE:
|
||
ord = 1;
|
||
break;
|
||
case RIGA_OMAGGI:
|
||
impon = r.imponibile_omaggio();
|
||
ord = 2;
|
||
break;
|
||
case RIGA_SPESEDOC:
|
||
ord = 3;
|
||
break;
|
||
case RIGA_PRESTAZIONI:
|
||
ord = 4;
|
||
break;
|
||
case RIGA_SCONTI:
|
||
ord = 5;
|
||
break;
|
||
case RIGA_DESCRIZIONI:
|
||
default:
|
||
return no_error;
|
||
break;
|
||
}
|
||
|
||
impon *= p; impon.round(firmdec); // was ndec
|
||
if (impon.is_zero())
|
||
return no_error;
|
||
|
||
const real imposta = tiva.imposta(impon, ndec);
|
||
|
||
// Le righe di sconto ad importo o percentuale vanno saltate
|
||
// Casistica sulle righe omaggio:
|
||
// quelle che non hanno addebito IVA devono venire scartate, quelle che hanno
|
||
// addebito IVA vengono aggiunte normalmente ed in piu' viene aggiunta
|
||
// una riga IVA con lo stesso imponibile ma di segno opposto, con un cod. IVA
|
||
// speciale per lo storno, proveniente da configurazione
|
||
|
||
const TString4 tipodet = r.get(RDOC_TIPODET);
|
||
|
||
TString80 key;
|
||
key.format("%d|%-4s|%c|%3d|%3d|%6ld|%s",
|
||
ord,(const char*)cod,c.tipo(),c.gruppo(),c.conto(),c.sottoconto(), (const char*)tipodet);
|
||
|
||
// Nel caso di documenti a zero tiene distinte IVA positiva e negativa
|
||
if (r.doc().totale_doc().is_zero())
|
||
{
|
||
if (impon < ZERO)
|
||
key << "|-";
|
||
else
|
||
key << "|+";
|
||
}
|
||
|
||
TRectype* iva = (TRectype*)objptr(key);
|
||
|
||
if (iva == NULL)
|
||
{
|
||
iva = new TRectype(LF_RMOVIVA);
|
||
iva->put(RMI_CODIVA, cod);
|
||
iva->put(RMI_TIPOCR, c.tipo_cr());
|
||
iva->put(RMI_INTRA, _caus->intra());
|
||
iva->put(RMI_TIPOC, c.tipo());
|
||
iva->put(RMI_GRUPPO, c.gruppo());
|
||
iva->put(RMI_CONTO, c.conto());
|
||
iva->put(RMI_SOTTOCONTO, c.sottoconto());
|
||
TAssoc_array::add(key, iva, true);
|
||
}
|
||
|
||
iva->add(RMI_IMPONIBILE, impon);
|
||
iva->put(RMI_TIPODET, tipodet);
|
||
iva->add(RMI_IMPOSTA, imposta);
|
||
if (ord != 5)
|
||
{
|
||
if (sconto_lordo) // Se e' settato il flag di contabilizzare anche gli sconti merce
|
||
{
|
||
const real sconto = -r.sconto(); // Imponibile dello sconto (positivo, quindi si cambia di segno)
|
||
if (!sconto.is_zero()) // Le righe Omaggio con Addebito IVA hanno comunque sconto ZERO!
|
||
{
|
||
TRiga_documento r_sconto(r);
|
||
r_sconto.put(RDOC_QTA, UNO);
|
||
r_sconto.put(RDOC_PREZZO, sconto);
|
||
add(r_sconto, _sco_perc_bill, ndec, p);
|
||
}
|
||
}
|
||
}
|
||
return no_error;
|
||
}
|
||
|
||
void TContabilizzazione::init()
|
||
{
|
||
_fcaus = new TLocalisamfile(LF_CAUSALI);
|
||
_frcaus = new TLocalisamfile(LF_RCAUSALI);// Per far andare TCausale
|
||
_attiv = new TLocalisamfile(LF_ATTIV); // Altrimenti TRegistro non va!
|
||
_part = new TLocalisamfile(LF_PARTITE);
|
||
_scad = new TLocalisamfile(LF_SCADENZE);
|
||
_pags = new TLocalisamfile(LF_PAGSCA); // Per far funzionare TPartita
|
||
_intra = new TLocalisamfile(LF_INTRA);
|
||
_rintra = new TLocalisamfile(LF_RINTRA);
|
||
_occas = new TLocalisamfile(LF_OCCAS);
|
||
_docfile = new TLocalisamfile(LF_DOC);
|
||
_rdocfile = new TLocalisamfile(LF_RIGHEDOC); // Per far funzionare TDocumento,TPartita ecc..
|
||
_anamag = new TLocalisamfile(LF_ANAMAG);
|
||
_saldi = new TLocalisamfile(LF_SALDI);
|
||
|
||
_cpg = new TTable("%CPG");
|
||
_val = new TTable("%VAL");
|
||
_prs = new TTable("PRS");
|
||
_spp = new TTable("SPP");
|
||
_caa = new TTable("CAA");
|
||
_cra = new TTable("CRA");
|
||
_gmc = new TTable("GMC");
|
||
_rfa = new TTable("RFA");
|
||
_cve = new TTable("CVE");
|
||
_cco = new TTable("CCO");
|
||
_clifo = new TRelation(LF_CLIFO);
|
||
_clifo->add(LF_CFVEN,"TIPOCF=TIPOCF|CODCF=CODCF");
|
||
_righe_iva = new TIVA_array;
|
||
|
||
_nump_iva = get_bool("B4");
|
||
_auto_data = false;
|
||
|
||
_can_write = true;
|
||
_error = no_error;
|
||
_nrow = 0;
|
||
_total_docs = 0L;
|
||
_caus = NULL;
|
||
_viswin = NULL;
|
||
}
|
||
|
||
TContabilizzazione::TContabilizzazione(const char* cod) : TElaborazione(cod)
|
||
{ init(); }
|
||
|
||
TContabilizzazione::TContabilizzazione(const TRectype& rec) : TElaborazione(rec)
|
||
{ init(); }
|
||
|
||
TContabilizzazione::~TContabilizzazione()
|
||
{
|
||
delete _clifo;
|
||
delete _cpg;
|
||
delete _val;
|
||
delete _gmc;
|
||
delete _rfa;
|
||
delete _cve;
|
||
delete _cco;
|
||
delete _prs;
|
||
delete _spp;
|
||
delete _caa;
|
||
delete _cra;
|
||
delete _anamag;
|
||
delete _saldi;
|
||
delete _fcaus;
|
||
delete _frcaus;
|
||
delete _attiv;
|
||
delete _part;
|
||
delete _scad;
|
||
delete _pags;
|
||
delete _intra;
|
||
delete _rintra;
|
||
delete _occas;
|
||
delete _docfile;
|
||
delete _rdocfile;
|
||
delete _righe_iva;
|
||
}
|
||
|
||
bool TContabilizzazione::load_parameters()
|
||
{
|
||
// if (_loaded)
|
||
// return true;
|
||
|
||
TConfig conf(CONFIG_DITTA, "ve");
|
||
_search_seq = new TToken_string(conf.get("RICERCACR"));
|
||
|
||
// costruisce la stringa che controlla la ricerca del conto costo/ricavo
|
||
// Attenzione! non esegue alcun controllo di consistenza sulla corretta sequenza
|
||
// presuppone che il programma di configurazione abbia generato correttamente
|
||
// il tutto.
|
||
|
||
if (_search_seq->empty_items())
|
||
return error_box(TR("Non <20> abilitata alcuna ricerca per il conto di costo/ricavo in configurazione."));
|
||
|
||
_sc_enabled = conf.get_bool("GesSal","cg");
|
||
_in_enabled = dongle().active(INAUT);
|
||
_nump_cfg = conf.get_bool("RifPro","cg");
|
||
|
||
int gr,co;
|
||
long so;
|
||
|
||
gr = conf.get_int("SCOPRCODCON","ve",1);
|
||
co = conf.get_int("SCOPRCODCON","ve",2);
|
||
so = conf.get_long("SCOPRCODCON","ve",3);
|
||
_sco_perc_bill.set(gr,co,so);
|
||
|
||
gr = conf.get_int("SCOIMCODCON","ve",1);
|
||
co = conf.get_int("SCOIMCODCON","ve",2);
|
||
so = conf.get_long("SCOIMCODCON","ve",3);
|
||
_sco_imp_bill.set(gr,co,so);
|
||
|
||
_contsclor = conf.get_bool("CONTSCLOR","ve");
|
||
|
||
_iva_sto = conf.get("IVASTO","ve");
|
||
|
||
gr = conf.get_int("OMACODCON","ve",1);
|
||
co = conf.get_int("OMACODCON","ve",2);
|
||
so = conf.get_long("OMACODCON","ve",3);
|
||
_conto_sto.set(gr,co,so);
|
||
|
||
gr = conf.get_int("SPINCODCONA","ve",1);
|
||
co = conf.get_int("SPINCODCONA","ve",2);
|
||
so = conf.get_long("SPINCODCONA","ve",3);
|
||
_spin_billa.set(gr,co,so);
|
||
|
||
gr = conf.get_int("SPINCODCONV","ve",1);
|
||
co = conf.get_int("SPINCODCONV","ve",2);
|
||
so = conf.get_long("SPINCODCONV","ve",3);
|
||
_spin_billv.set(gr,co,so);
|
||
|
||
gr = conf.get_int("SPBOCODCONA","ve",1);
|
||
co = conf.get_int("SPBOCODCONA","ve",2);
|
||
so = conf.get_long("SPBOCODCONA","ve",3);
|
||
_spbo_billa.set(gr,co,so);
|
||
|
||
gr = conf.get_int("SPBOCODCONV","ve",1);
|
||
co = conf.get_int("SPBOCODCONV","ve",2);
|
||
so = conf.get_long("SPBOCODCONV","ve",3);
|
||
_spbo_billv.set(gr,co,so);
|
||
|
||
_spin_cod = conf.get("SPINCODIVA","ve");
|
||
_spbo_cod = conf.get("SPBOCODIVA","ve");
|
||
|
||
_check_prev_cont = conf.get_bool("CHECKPREVCONT","ve");
|
||
_fld_cms_cont = conf.get("CMSCNTFIELD","ve");
|
||
|
||
return true;
|
||
}
|
||
|
||
bool TContabilizzazione::test_swap()
|
||
{
|
||
const char sez = _caus->sezione_clifo();
|
||
TipoIVA t = _caus->reg().iva();
|
||
|
||
if (t == nessuna_iva)
|
||
{
|
||
TBill c;
|
||
|
||
_caus->bill(1, c);
|
||
char tipocf = c.tipo();
|
||
|
||
if (tipocf == 'C')
|
||
t = iva_vendite;
|
||
else
|
||
{
|
||
if (tipocf == 'F')
|
||
t = iva_acquisti;
|
||
else
|
||
{
|
||
if (_caus->tipo_doc() == "FA")
|
||
t = iva_acquisti;
|
||
else
|
||
t = iva_vendite;
|
||
}
|
||
}
|
||
|
||
}
|
||
const bool s = (t == iva_vendite) ^ (sez == 'D');
|
||
|
||
return s;
|
||
}
|
||
|
||
error_type TContabilizzazione::get_next_reg_num(long& nr)
|
||
{
|
||
// reperisce l'ultimo numero di registrazione disponibile
|
||
_error = no_error;
|
||
TLocalisamfile mov(LF_MOV);
|
||
nr = 1L;
|
||
if (mov.last() == NOERR)
|
||
{
|
||
nr += mov.get_long(MOV_NUMREG);
|
||
if (nr <= 0) // Quando mai succede?
|
||
_error = nr_reg_error;
|
||
}
|
||
return _error;
|
||
}
|
||
|
||
long TContabilizzazione::doc_contabilized(const TDocumento& doc, bool anticipo) const
|
||
{
|
||
const char* const key[4] = { DOC_PROVV, DOC_ANNO, DOC_CODNUM, DOC_NDOC };
|
||
// NON usare la cache qui!!!!!!!!!!!!!!!!!!!!!!
|
||
|
||
long nreg = doc.get_long(anticipo ? DOC_NUMANT : DOC_NUMREG);
|
||
if (nreg > 0)
|
||
{
|
||
TLocalisamfile mov(LF_MOV);
|
||
mov.put(MOV_NUMREG, nreg);
|
||
if (mov.read() == NOERR) // Il movimento esiste!
|
||
{
|
||
// Controlla che il movimento abbia ancora il riferimento esatto al documento
|
||
TString8 dkey, dval;
|
||
for (int k = 0; k < 4; k++)
|
||
{
|
||
dkey = "D"; dkey << key[k];
|
||
dval = mov.get(dkey);
|
||
if (dval != doc.get(key[k]))
|
||
{
|
||
nreg = 0; // La chiave non corrisponde pi<70>: forse l'hanno cancellato e reinserito
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
nreg = 0; // Il movimento non esiste pi<70>: l'hanno cancellato!
|
||
}
|
||
else if (!anticipo)
|
||
{
|
||
const TDate data_reg = _auto_data ? doc.get_date(DOC_DATADOC) : _data_reg;
|
||
const TCausale* caus = get_caus(doc, data_reg.year());
|
||
TLocalisamfile mov(LF_MOV);
|
||
mov.setkey(3);
|
||
mov.put(MOV_TIPO, doc.clifor().tipo());
|
||
mov.put(MOV_CODCF, doc.clifor().codice());
|
||
mov.put(MOV_DATAREG, data_reg);
|
||
for (int err = mov.read(_isgteq); err == NOERR; err = mov.next())
|
||
{
|
||
const TDate d = mov.get(MOV_DATAREG);
|
||
if (d != data_reg)
|
||
break;
|
||
const TString& cau = mov.get(MOV_CODCAUS);
|
||
if (cau != caus->codice())
|
||
continue; // Altra causale, probabilmente anticipo
|
||
|
||
// Controlla che il movimento abbia il riferimento esatto al documento
|
||
TString8 dkey, dval;
|
||
int k = 0;
|
||
for (k = 0; k < 4; k++)
|
||
{
|
||
dkey = "D"; dkey << key[k];
|
||
dval = mov.get(dkey);
|
||
if (dval != doc.get(key[k]))
|
||
break; // La chiave non corrisponde: <20> un altro documento
|
||
}
|
||
if (k == 4) // Ricontabilizziaaamoo!
|
||
{
|
||
nreg = mov.get_long(MOV_NUMREG);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
return nreg;
|
||
}
|
||
|
||
TCausale* TContabilizzazione::get_caus(const TDocumento& doc, const int year) const
|
||
{
|
||
TString4 codcaus;
|
||
TToken_string key;
|
||
|
||
if (_fld_cms_cont.full())
|
||
{
|
||
const TString& cms = doc.commessa_principale();
|
||
if (cms.full())
|
||
{
|
||
key.add(cms);
|
||
const TString16 fld_val = cache().get(LF_COMMESSE, key, _fld_cms_cont);
|
||
if (fld_val.full())
|
||
{
|
||
key = "CTCMS";
|
||
key.add(doc.tipo().codice());
|
||
key.add(fld_val);
|
||
codcaus = cache().get(LF_MULTIREL, key, "DATA");
|
||
}
|
||
}
|
||
}
|
||
if (codcaus.blank())
|
||
{
|
||
key = doc.get(DOC_TIPOCF); key.add(doc.get(DOC_CODCF));
|
||
const TRectype& cfven = cache().get(LF_CFVEN, key);
|
||
|
||
codcaus = cfven.get(doc.is_nota_credito() ? CFV_CODCAUSNC : CFV_CODCAUS);
|
||
|
||
if (codcaus.blank())
|
||
codcaus = doc.tipo().causale(); // Istanzia la causale del documento corrente...
|
||
}
|
||
|
||
if (_caus != NULL && _caus->codice() == codcaus && _caus->reg().year() == year)
|
||
return _caus;
|
||
if (_caus != NULL)
|
||
{
|
||
delete _caus;
|
||
_caus = NULL;
|
||
}
|
||
if (codcaus.full())
|
||
_caus = new TCausale(codcaus, year);
|
||
|
||
return _caus;
|
||
}
|
||
|
||
error_type TContabilizzazione::compile_head_mov(TDocumento& doc)
|
||
// Compila la testata
|
||
{
|
||
const bool acquisto = doc.get_char(DOC_TIPOCF) == 'F';
|
||
// Reperisce la data documento
|
||
const TDate datadoc(doc.data());
|
||
if (!datadoc.ok())
|
||
{
|
||
_error = datadoc_error;
|
||
return _error;
|
||
}
|
||
|
||
// reperisce la data di registrazione, che e' anche la data di competenza ed
|
||
// eventualmente la data74ter se nel registro della causale vi e' scritta l'informazione
|
||
// sulle agenzie di viaggio.
|
||
// se si e' specificata la data automatica prende invece la data del documento
|
||
const TDate data_reg(_auto_data ? datadoc : _data_reg);
|
||
|
||
// reperisce il codice anno esercizio,
|
||
const int cod_es = esercizi().date2esc(data_reg);
|
||
if (cod_es <= 0)
|
||
{
|
||
_error = nr_es_error;
|
||
return _error;
|
||
}
|
||
|
||
// reperisce l'ultimo numero di registrazione disponibile
|
||
long numreg = doc_contabilized(doc, false);
|
||
const bool recontabilizing = numreg > 0;
|
||
if (recontabilizing)
|
||
{
|
||
const TRectype& mov = cache().get(LF_MOV, numreg);
|
||
TString msg; msg.format("*** Il movimento %ld <20> gi<67> stato ", numreg);
|
||
if (mov.get_bool(MOV_REGST))
|
||
{
|
||
msg << "stampato su bollato";
|
||
_viswin->add_line(msg);
|
||
} else
|
||
if (mov.get_bool(MOV_STAMPATO))
|
||
{
|
||
msg << "stampato sul giornale";
|
||
_viswin->add_line(msg);
|
||
} else
|
||
if (mov.get_bool(MOV_INVIATO))
|
||
{
|
||
msg << "inviato ad altra contabilit<69>";
|
||
_viswin->add_line(msg);
|
||
}
|
||
msg.format("--- Il documento verr<72> ricontabilizzato nel movimento %ld", numreg);
|
||
_viswin->add_line(msg);
|
||
}
|
||
else
|
||
{
|
||
_error = get_next_reg_num(numreg);
|
||
if (_error != no_error)
|
||
return _error;
|
||
}
|
||
|
||
const TCodice_numerazione cod_num(doc.numerazione());
|
||
// calcola il numero documento aggiungendo l'eventuale prefisso/postfisso.
|
||
TString numdoc;
|
||
cod_num.complete_num(doc.numero(), numdoc);
|
||
if (acquisto)
|
||
{
|
||
const TString& numdocrif = doc.get(DOC_NUMDOCRIF);
|
||
if (numdocrif.not_empty())
|
||
numdoc = numdocrif;
|
||
}
|
||
|
||
if (numdoc.empty() || !cod_num.ok())
|
||
{
|
||
_error = nr_doc_error;
|
||
return _error;
|
||
}
|
||
numdoc.upper(); // Il numero documento e' uppercase!
|
||
|
||
const TTipo_documento& tipo = doc.tipo();
|
||
|
||
// Istanzia la causale del documento corrente...
|
||
_caus = get_caus(doc, data_reg.year());
|
||
|
||
_righe_iva->set_caus(_caus);
|
||
if (_caus == NULL || !_caus->ok())
|
||
{
|
||
_error = caus_error;
|
||
return _error;
|
||
}
|
||
//_righe_iva->set_caus(_caus); // Appena fatto sopra
|
||
|
||
if (doc.in_valuta() && !_caus->valuta())
|
||
{
|
||
_error = cauval_error;
|
||
return _error;
|
||
}
|
||
|
||
// per reperire il tipo documento ed il tipo movimento
|
||
// reperisce la descrizione dal tipo documento e la completa con la data documento ed il
|
||
// numero documento
|
||
const bool short_rif = pack_rif();
|
||
TString descr;
|
||
|
||
if (!short_rif)
|
||
{
|
||
doc.riferimento(descr);
|
||
if (descr.empty()) descr = tipo.descrizione();
|
||
if (descr.full())
|
||
descr << ' ';
|
||
}
|
||
|
||
const TString16 rif = doc.get(DOC_NUMDOCRIF);
|
||
const bool use_rif = _caus->iva() == iva_acquisti && rif.not_empty();
|
||
if (use_rif)
|
||
{
|
||
descr << "n. " << rif;
|
||
const TString & data_rif = doc.get_date(DOC_DATADOCRIF).string(short_rif ? brief : full);
|
||
descr << " del " << data_rif;
|
||
}
|
||
else
|
||
{
|
||
descr << "n. " << doc.numero();
|
||
descr << " del " << datadoc.string(short_rif ? brief : full);
|
||
}
|
||
|
||
if (doc.in_valuta())
|
||
{
|
||
descr << " " << doc.get(DOC_CODVAL);
|
||
descr << " " << doc.totale_doc().stringa();
|
||
}
|
||
|
||
// Codice registro IVA
|
||
const TRegistro& registro = _caus->reg();
|
||
const bool iva_mov = registro.ok();
|
||
long ult_prot = 0;
|
||
|
||
if (iva_mov)
|
||
{
|
||
if (recontabilizing)
|
||
{
|
||
const TRectype& mov = cache().get(LF_MOV, numreg);
|
||
ult_prot = mov.get_long(MOV_PROTIVA);
|
||
}
|
||
else
|
||
{
|
||
if (_nump_iva) // Reperisce l'ultimo numero di protocollo dal registro IVA
|
||
{
|
||
ult_prot = registro.protocol() + 1;
|
||
if (ult_prot <= 0)
|
||
{
|
||
_error = ultprot_error;
|
||
return _error;
|
||
}
|
||
}
|
||
else // oppure dal numero di documento
|
||
ult_prot = doc.numero();
|
||
}
|
||
}
|
||
|
||
// Reperisce la valuta
|
||
TString4 codval;
|
||
real cambio;
|
||
TDate datacam;
|
||
if (doc.in_valuta())
|
||
{
|
||
codval = doc.valuta(); codval.trim();
|
||
cambio = doc.cambio();
|
||
datacam = doc.get_date(DOC_DATACAMBIO);
|
||
if (::is_true_value(codval))
|
||
{
|
||
_val->put("CODTAB",codval);
|
||
if (_val->read() != NOERR)
|
||
return _error = val_error;
|
||
if (cambio.is_zero())
|
||
return _error = change_error;
|
||
}
|
||
else
|
||
{
|
||
if (cambio != ZERO)
|
||
return _error = change_error;
|
||
}
|
||
}
|
||
|
||
// Dati del cliente...
|
||
const TString4 tipocf(doc.get(DOC_TIPOCF));
|
||
const long codcf = doc.get_long(DOC_CODCF);
|
||
TString80 occas;
|
||
{
|
||
TLocalisamfile& cli_file = _clifo->lfile();
|
||
cli_file.put(CLI_TIPOCF,tipocf); cli_file.put(CLI_CODCF,codcf);
|
||
if (_clifo->read(_isequal) == NOERR) // posiziona il cliente una volta per tutte
|
||
{
|
||
if (cli_file.get_bool(CLI_OCCAS))
|
||
{
|
||
occas = doc.get(DOC_OCFPI);
|
||
TLocalisamfile ocf(LF_OCCAS);
|
||
ocf.put(OCC_CFPI,occas);
|
||
if (ocf.read() != NOERR)
|
||
{
|
||
_error = clifo_error;
|
||
return _error;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (!doc.tipo().clifo_optional())
|
||
{
|
||
_error = clifo_error;
|
||
return _error;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Codice pagamento
|
||
const TString4 codpag = doc.get(DOC_CODPAG);
|
||
if (sc_enabled(data_reg) || codpag.full()) // La condizione di pagamento va controllata
|
||
{ // se e' abilitato il saldaconto o se e' stata inserita
|
||
_cpg->put("CODTAB",codpag);
|
||
if (_cpg->read() != NOERR)
|
||
{
|
||
_error = codpag_error;
|
||
return _error;
|
||
}
|
||
}
|
||
|
||
// Mo' riempie il record della incornata (testata)
|
||
TRectype& mov_rec = _movimento->curr();
|
||
mov_rec.zero();
|
||
mov_rec.put(MOV_ANNOES,cod_es); mov_rec.put(MOV_NUMREG,numreg);
|
||
mov_rec.put(MOV_DATAREG,data_reg); mov_rec.put(MOV_DATACOMP,data_reg);
|
||
if (use_rif)
|
||
{
|
||
mov_rec.put(MOV_NUMDOC, rif);
|
||
const TString& data_rif = doc.get(DOC_DATADOCRIF);
|
||
mov_rec.put(MOV_DATADOC, data_rif);
|
||
}
|
||
else
|
||
{
|
||
mov_rec.put(MOV_DATADOC,datadoc);
|
||
mov_rec.put(MOV_NUMDOC,numdoc);
|
||
}
|
||
mov_rec.put(MOV_TIPODOC,_caus->tipo_doc());
|
||
mov_rec.put(MOV_CODCAUS,_caus->codice());
|
||
mov_rec.put(MOV_DESCR, descr);
|
||
mov_rec.put(MOV_TIPOMOV,char(_caus->tipomov()+'0'));
|
||
mov_rec.put(MOV_ANNOIVA,data_reg.year());
|
||
mov_rec.put(MOV_CODVAL,codval);
|
||
mov_rec.put(MOV_CAMBIO,cambio);
|
||
mov_rec.put(MOV_DATACAM,datacam);
|
||
mov_rec.put(MOV_CODPAG,codpag);
|
||
|
||
TCurrency_documento totdocval(doc.totale_doc(), doc);
|
||
|
||
if (iva_mov)
|
||
{
|
||
if (registro.agenzia_viaggi())
|
||
mov_rec.put(MOV_DATA74TER,data_reg);
|
||
mov_rec.put(MOV_REG, registro.name());
|
||
mov_rec.put(MOV_PROTIVA,ult_prot);
|
||
mov_rec.put(MOV_TIPO,tipocf);
|
||
mov_rec.put(MOV_CODCF,codcf);
|
||
mov_rec.put(MOV_OCFPI,occas);
|
||
|
||
TString4 codvali;
|
||
real cambioi;
|
||
|
||
if (_caus->iva() == iva_acquisti)
|
||
{
|
||
const TString& tdoc_cont = doc.tipo().totale_doc_cont();
|
||
if (tdoc_cont.full())
|
||
totdocval.set_num(doc.get_real(tdoc_cont));
|
||
|
||
if (_caus->intra())
|
||
{
|
||
TCurrency_documento imposta(doc.imposta(), doc);
|
||
totdocval -= imposta;
|
||
|
||
imposta.change_to_firm_val();
|
||
mov_rec.put(MOV_RITFIS, imposta.get_num());
|
||
|
||
codvali = _clifo->curr().get("VALINTRA");
|
||
cambioi = cambio;
|
||
if (codvali.full() && codvali != codval)
|
||
{
|
||
mov_rec.put(MOV_CODVALI,codvali);
|
||
TExchange c(codvali);
|
||
cambioi = c.get_change();
|
||
mov_rec.put(MOV_CAMBIOI, cambioi);
|
||
}
|
||
else
|
||
{
|
||
codvali = codval;
|
||
cambioi = cambio;
|
||
if (_caus->valintra() && codvali.blank())
|
||
{
|
||
codvali = TCurrency::get_firm_val();
|
||
if (codvali.empty())
|
||
codvali = TCurrency::get_euro_val();
|
||
cambioi = UNO;
|
||
}
|
||
|
||
mov_rec.put(MOV_CODVALI,codval);
|
||
mov_rec.put(MOV_CAMBIOI,cambioi);
|
||
codvali = codval;
|
||
}
|
||
TCurrency corrval(totdocval);
|
||
TCurrency corrlire(corrval);
|
||
corrval.change_value(codvali, cambioi);
|
||
corrlire.change_to_firm_val();
|
||
mov_rec.put(MOV_CORRLIRE,corrlire.get_num());
|
||
if (_caus->valintra())
|
||
mov_rec.put(MOV_CORRVALUTA,corrval.get_num());
|
||
|
||
TDate dataintra = data_reg;
|
||
if (doc.tipo().nota_credito())
|
||
{
|
||
TDate d = doc.get_date(DOC_DATADOCRIF);
|
||
if (d.ok() && d < data_reg)
|
||
dataintra = d;
|
||
}
|
||
mov_rec.put(MOV_DATACOMPI, dataintra);
|
||
}
|
||
else
|
||
{
|
||
if (_caus->reverse_charge())
|
||
{
|
||
TCurrency_documento imposta(doc.imposta(), doc);
|
||
totdocval -= imposta;
|
||
imposta.change_to_firm_val();
|
||
mov_rec.put(MOV_REVCHARGE, imposta.get_num()); // 15-12-2015 was MOV_RITFIS
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (_caus->intra())
|
||
{
|
||
TCurrency corrval(totdocval);
|
||
TCurrency corrlire(corrval);
|
||
|
||
codvali = codval;
|
||
cambioi = cambio;
|
||
if (_caus->valintra() && codvali.empty())
|
||
{
|
||
codvali = TCurrency::get_firm_val();
|
||
|
||
if (codvali.empty())
|
||
codvali = TCurrency::get_euro_val();
|
||
cambioi = UNO;
|
||
}
|
||
|
||
mov_rec.put(MOV_CODVALI,codvali);
|
||
mov_rec.put(MOV_CAMBIOI,cambioi);
|
||
corrlire.change_to_firm_val();
|
||
mov_rec.put(MOV_CORRLIRE, corrlire.get_num());
|
||
if (_caus->valintra())
|
||
mov_rec.put(MOV_CORRVALUTA, corrval.get_num());
|
||
|
||
TDate dataintra = data_reg;
|
||
if (doc.tipo().nota_credito())
|
||
{
|
||
const TDate d = doc.get_date(DOC_DATADOCRIF);
|
||
if (d.ok() && d < data_reg)
|
||
dataintra = d;
|
||
}
|
||
mov_rec.put(MOV_DATACOMPI, dataintra);
|
||
}
|
||
else
|
||
{
|
||
// Imposta nelle fatture di vendita normali il flag di split payment
|
||
if (mov_rec.get_char(MOV_SPLITPAY) <= ' ')
|
||
mov_rec.put(MOV_SPLITPAY, is_split_payment(mov_rec) ? 'S': 'N');
|
||
}
|
||
}
|
||
}
|
||
|
||
if (doc.in_valuta())
|
||
{
|
||
TCurrency totdoclit(totdocval);
|
||
totdoclit.change_to_firm_val();
|
||
mov_rec.put(MOV_TOTDOC,totdoclit.get_num());
|
||
mov_rec.put(MOV_TOTDOCVAL,totdocval.get_num());
|
||
}
|
||
else
|
||
mov_rec.put(MOV_TOTDOC,totdocval.get_num());
|
||
|
||
// Memorizza il movimento contabile di destinazione!
|
||
doc.put(DOC_NUMREG, numreg);
|
||
// Scrive sulla testata del movimento il numero di documento originale
|
||
mov_rec.put(MOV_DPROVV, doc.get(DOC_PROVV));
|
||
mov_rec.put(MOV_DANNO, doc.get(DOC_ANNO));
|
||
mov_rec.put(MOV_DCODNUM, doc.get(DOC_CODNUM));
|
||
mov_rec.put(MOV_DNDOC, doc.get(DOC_NDOC));
|
||
mov_rec.put(MOV_LIQDIFF, doc.get(DOC_LIQDIFF));
|
||
mov_rec.put(MOV_IVAXCASSA, doc.get(DOC_IVAXCASSA));
|
||
mov_rec.put(MOV_NOLEGGIO, doc.get(DOC_NOLEGGIO));
|
||
mov_rec.put(MOV_CONTSEP, doc.get(DOC_CONTSEP));
|
||
|
||
return _error;
|
||
}
|
||
|
||
error_type TContabilizzazione::compile_head_mov_re(TDocumento& doc)
|
||
// Compila la testata
|
||
{
|
||
TRectype& mov_rec = _movimento->curr();
|
||
|
||
const bool acquisto = doc.get_char(DOC_TIPOCF) == 'F';
|
||
// Reperisce la data documento
|
||
const TDate datadoc(doc.data());
|
||
if (!datadoc.ok())
|
||
{
|
||
_error = datadoc_error;
|
||
return _error;
|
||
}
|
||
|
||
// reperisce la data di registrazione, che e' anche la data di competenza ed
|
||
// eventualmente la data74ter se nel registro della causale vi e' scritta l'informazione
|
||
// sulle agenzie di viaggio.
|
||
// se si e' specificata la data automatica prende invece la data del documento
|
||
const TDate data_reg(_auto_data ? datadoc : _data_reg);
|
||
|
||
// reperisce il codice anno esercizio,
|
||
const int cod_es = esercizi().date2esc(data_reg);
|
||
if (cod_es <= 0)
|
||
{
|
||
_error = nr_es_error;
|
||
return _error;
|
||
}
|
||
|
||
// reperisce l'ultimo numero di registrazione disponibile
|
||
long numreg = doc_contabilized(doc, false);
|
||
const bool recontabilizing = numreg > 0;
|
||
if (recontabilizing)
|
||
{
|
||
const TRectype& mov = cache().get(LF_MOV, numreg);
|
||
TString msg; msg.format("*** Il movimento %ld <20> gi<67> stato ", numreg);
|
||
if (mov.get_bool(MOV_REGST))
|
||
{
|
||
msg << "stampato su bollato";
|
||
_viswin->add_line(msg);
|
||
return no_error;
|
||
}
|
||
if (mov.get_bool(MOV_STAMPATO))
|
||
{
|
||
msg << "stampato sul giornale";
|
||
_viswin->add_line(msg);
|
||
return no_error;
|
||
}
|
||
if (mov.get_bool(MOV_INVIATO))
|
||
{
|
||
msg << "inviato ad altra contabilit<69>";
|
||
_viswin->add_line(msg);
|
||
return no_error;
|
||
}
|
||
msg.format("--- Il documento verr<72> ricontabilizzato nel movimento contabile %ld", numreg);
|
||
_viswin->add_line(msg);
|
||
}
|
||
else
|
||
{
|
||
_error = get_next_reg_num(numreg);
|
||
if (_error != no_error)
|
||
return _error;
|
||
}
|
||
|
||
const TCodice_numerazione cod_num(doc.numerazione());
|
||
// calcola il numero documento aggiungendo l'eventuale prefisso/postfisso.
|
||
TString numdoc;
|
||
cod_num.complete_num(doc.numero(), numdoc);
|
||
if (acquisto)
|
||
{
|
||
const TString& numdocrif = doc.get(DOC_NUMDOCRIF);
|
||
if (numdocrif.full())
|
||
numdoc = numdocrif;
|
||
}
|
||
|
||
if (numdoc.empty() || !cod_num.ok())
|
||
{
|
||
_error = nr_doc_error;
|
||
return _error;
|
||
}
|
||
numdoc.upper(); // Il numero documento e' uppercase!
|
||
|
||
// Istanzia la causale del documento corrente...
|
||
|
||
_caus = get_caus(doc, data_reg.year());
|
||
if (_caus == NULL || !_caus->ok() || _caus->iva() != nessuna_iva)
|
||
{
|
||
_error = causre_error;
|
||
return _error;
|
||
}
|
||
_righe_iva->set_caus(_caus);
|
||
_movimento->set_caus(_caus);
|
||
|
||
// per reperire il tipo documento ed il tipo movimento
|
||
// reperisce la descrizione dal tipo documento e la completa con la data documento ed il
|
||
// numero documento
|
||
const bool short_rif = pack_rif();
|
||
TString descr;
|
||
|
||
if (!short_rif)
|
||
{
|
||
doc.riferimento(descr);
|
||
if (descr.empty()) descr = doc.tipo().descrizione();
|
||
if (descr.full())
|
||
descr << ' ';
|
||
}
|
||
|
||
const TString16 rif = doc.get(DOC_NUMDOCRIF);
|
||
const bool use_rif = _caus->iva() == iva_acquisti && rif.full();
|
||
if (use_rif)
|
||
{
|
||
descr << "n. " << rif;
|
||
const TString & data_rif = doc.get_date(DOC_DATADOCRIF).string(short_rif ? brief : full);
|
||
descr << " del " << data_rif;
|
||
}
|
||
else
|
||
{
|
||
descr << "n. " << doc.numero();
|
||
descr << " del " << datadoc.string(short_rif ? brief : full);
|
||
}
|
||
|
||
// Dati del cliente...
|
||
const TString4 tipocf(doc.get(DOC_TIPOCF));
|
||
const long codcf = doc.get_long(DOC_CODCF);
|
||
TString80 occas;
|
||
{
|
||
TLocalisamfile& cli_file = _clifo->lfile();
|
||
cli_file.put(CLI_TIPOCF,tipocf); cli_file.put(CLI_CODCF,codcf);
|
||
if (_clifo->read(_isequal) == NOERR) // posiziona il cliente una volta per tutte
|
||
{
|
||
if (cli_file.get_bool(CLI_OCCAS))
|
||
{
|
||
occas = doc.get(DOC_OCFPI);
|
||
TLocalisamfile ocf(LF_OCCAS);
|
||
ocf.put(OCC_CFPI,occas);
|
||
if (ocf.read() != NOERR)
|
||
{
|
||
_error = clifo_error;
|
||
return _error;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (!doc.tipo().clifo_optional())
|
||
{
|
||
_error = clifo_error;
|
||
return _error;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Mo' riempie il record della incornata (testata)
|
||
mov_rec.zero();
|
||
mov_rec.put(MOV_ANNOES,cod_es); mov_rec.put(MOV_NUMREG,numreg);
|
||
mov_rec.put(MOV_DATAREG,data_reg); mov_rec.put(MOV_DATACOMP,data_reg);
|
||
if (use_rif)
|
||
{
|
||
mov_rec.put(MOV_NUMDOC, rif);
|
||
const TString & data_rif = doc.get(DOC_DATADOCRIF);
|
||
mov_rec.put(MOV_DATADOC,data_rif);
|
||
}
|
||
else
|
||
{
|
||
mov_rec.put(MOV_DATADOC,datadoc);
|
||
mov_rec.put(MOV_NUMDOC,numdoc);
|
||
}
|
||
mov_rec.put(MOV_CODCAUS,_caus->codice());
|
||
mov_rec.put(MOV_TIPODOC,_caus->tipo_doc());
|
||
mov_rec.put(MOV_DESCR,descr);
|
||
mov_rec.put(MOV_CODCF,codcf);
|
||
|
||
// Memorizza il movimento contabile di destinazione!
|
||
doc.put(DOC_NUMREG, numreg);
|
||
// Scrive sulla testata del movimento il numero di documento originale
|
||
mov_rec.put(MOV_DPROVV, doc.get(DOC_PROVV));
|
||
mov_rec.put(MOV_DANNO, doc.get(DOC_ANNO));
|
||
mov_rec.put(MOV_DCODNUM, doc.get(DOC_CODNUM));
|
||
mov_rec.put(MOV_DNDOC, doc.get(DOC_NDOC));
|
||
mov_rec.put(MOV_LIQDIFF, doc.get(DOC_LIQDIFF));
|
||
mov_rec.put(MOV_IVAXCASSA, doc.get(DOC_IVAXCASSA));
|
||
mov_rec.put(MOV_NOLEGGIO, doc.get(DOC_NOLEGGIO));
|
||
mov_rec.put(MOV_CONTSEP, doc.get(DOC_CONTSEP));
|
||
|
||
|
||
return _error;
|
||
}
|
||
|
||
error_type TContabilizzazione::search_costo_ricavo(TBill& conto, const TRiga_documento& r, real & amount_to_split, const real & valore)
|
||
{
|
||
const int items = _search_seq->items();
|
||
const TRectype& cli_file = _clifo->curr(); // YES, arriva qui dentro quando la relazione e' gia' posizionata
|
||
const bool is_cli = cli_file.get_char(CLI_TIPOCF) != 'F';
|
||
bool skip_art_related = false;
|
||
bool skip_clifo = _clifo->bad();
|
||
const TCodiceIVA codiva(r.get(RDOC_CODIVA));
|
||
|
||
const char t = r.tipo().tipo();
|
||
switch (t)
|
||
{
|
||
case RIGA_OMAGGI: // righe omaggio come articoli spiaccicato identico (avranno imponibile 0)
|
||
case RIGA_MERCE: // righe di merce
|
||
{
|
||
// posiziona l'anagrafica sull'articolo specificato sulla ..iga
|
||
_anamag->put(ANAMAG_CODART,r.get(RDOC_CODARTMAG));
|
||
if (_anamag->read() != NOERR) // se non trova l'articolo saltera' anche gmc,smc,rfa.
|
||
skip_art_related = true;
|
||
|
||
TString16 tok;
|
||
// Scorre la stringa di ricerca
|
||
for (int i=0;good() && i<items;i++)
|
||
{
|
||
tok = _search_seq->get(i);
|
||
if (tok == "CF")
|
||
{
|
||
if (skip_clifo) continue;
|
||
int gr = cli_file.get_int(CLI_GRUPPORIC);
|
||
int co = cli_file.get_int(CLI_CONTORIC);
|
||
long so = cli_file.get_long(CLI_SOTTOCRIC);
|
||
conto.set(gr,co,so);
|
||
if (conto.ok()) break; // se lo trova esce (tutti != 0)
|
||
} else
|
||
if (tok == "CA")
|
||
{
|
||
CHECK(_caus,"Causale documento non valida");
|
||
if (_caus->IVA2bill(codiva,conto)) break; // se lo trova esce
|
||
} else
|
||
if (tok == "AR")
|
||
{
|
||
if (skip_art_related) continue;
|
||
int gr = _anamag->get_int(is_cli ? ANAMAG_GRUPPOV : ANAMAG_GRUPPOA);
|
||
int co = _anamag->get_int(is_cli ? ANAMAG_CONTOV : ANAMAG_CONTOA);
|
||
long so = _anamag->get_long(is_cli ? ANAMAG_SOTTOCV : ANAMAG_SOTTOCA);
|
||
conto.set(gr,co,so);
|
||
if (!conto.ok()) // se il conto non c'e' guarda la categoria acquisti/vendite
|
||
{
|
||
TTable& t = is_cli ? *_cra : *_caa;
|
||
t.put("CODTAB", _anamag->get(is_cli ? ANAMAG_CATCONV : ANAMAG_CATCONA));
|
||
if (t.read() == NOERR)
|
||
{
|
||
gr = t.get_int("I0");
|
||
co = t.get_int("I1");
|
||
so = t.get_long("I2");
|
||
conto.set(gr, co, so);
|
||
}
|
||
}
|
||
if (conto.ok())
|
||
break;
|
||
} else
|
||
if (tok == "GM" || tok == "SM" || tok == "RF")
|
||
{
|
||
if (skip_art_related) continue;
|
||
const bool is_fis = tok == "RF";
|
||
TTable& tab = is_fis ? *_rfa : *_gmc;
|
||
TString16 codtab =_anamag->get(is_fis ? ANAMAG_RAGGFIS : ANAMAG_GRMERC);
|
||
if (tok == "GM" && codtab.len() > 3)
|
||
codtab.cut(3); // gli ultimi 2 si riferiscono al sottogruppo.
|
||
tab.put("CODTAB",codtab);
|
||
if (tab.read() == NOERR)
|
||
{
|
||
int gr = tab.get_int(is_cli ? "I3" : "I0");
|
||
int co = tab.get_int(is_cli ? "I4" : "I1");
|
||
long so = tab.get_long(is_cli ? "I5" : "I2");
|
||
conto.set(gr, co, so);
|
||
}
|
||
if (conto.ok())
|
||
break;
|
||
} else
|
||
if (tok == "CV" || tok == "CC")
|
||
{
|
||
const bool is_cve = tok == "CV";
|
||
if (is_cve && !is_cli) continue; // se e' un fornitore salta questa condizione
|
||
TTable& t = is_cve ? *_cve : *_cco;
|
||
TString16 cod = is_cve ? r.doc().get(DOC_CATVEN) : EMPTY_STRING;
|
||
if (cod.empty())
|
||
{
|
||
if (skip_clifo) continue; // se non aveva trovato il cliente salta al prossimo
|
||
cod = _clifo->curr(LF_CFVEN).get(is_cve ? CFV_CATVEN : CFV_CODCATC);
|
||
}
|
||
t.put("CODTAB",cod);
|
||
if (t.read() == NOERR)
|
||
{
|
||
const bool x = (is_cve || is_cli);
|
||
const int gr = t.get_int(x ? "I3" : "I0");
|
||
const int co = t.get_int(x ? "I4" : "I1");
|
||
const long so = t.get_long(x ? "I5": "I2");
|
||
conto.set(gr,co,so);
|
||
}
|
||
if (conto.ok())
|
||
break;
|
||
} else
|
||
if (tok == "VM")
|
||
{
|
||
if (!is_cli) continue; // se non e' un cliente salta questa condizione
|
||
// Costruisco il codice Categoria conto vendite articoli(3)+Categoria di vendita cliente(2)
|
||
TString4 catven = r.doc().get(DOC_CATVEN);
|
||
if (catven.blank())
|
||
catven = _clifo->curr(LF_CFVEN).get(CFV_CATVEN);
|
||
|
||
TString8 cod = _anamag->get(ANAMAG_CATCONV);
|
||
cod.left_just(3) << catven;
|
||
const TRectype* t = &cache().get("&CVM", cod);
|
||
|
||
if (!t->empty())
|
||
{
|
||
const int gr = t->get_int("I0");
|
||
const int co = t->get_int("I1");
|
||
const long so = t->get_long("I2");
|
||
conto.set(gr,co,so);
|
||
if (conto.ok())
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
break; // case 'M'
|
||
case RIGA_PRESTAZIONI: // righe prestazione
|
||
case RIGA_SPESEDOC: // righe spese
|
||
{
|
||
const TSpesa_prest & spesa = r.spesa();
|
||
|
||
int gr = spesa.get_int(is_cli ? "I0" : "I3");
|
||
int co = spesa.get_int(is_cli ? "I1" : "I4");
|
||
long so = spesa.get_long(is_cli ? "I2" : "I5");
|
||
conto.set(gr,co,so);
|
||
if (!conto.ok())
|
||
{
|
||
gr = r.get_int(RDOC_QTAGG1);
|
||
co = r.get_int(RDOC_QTAGG2);
|
||
so = r.get_long(RDOC_QTAGG3);
|
||
conto.set(gr,co,so);
|
||
|
||
if (!conto.ok()) // Cerca il conto nella stringa di ricerca (solo per prestazioni)
|
||
{
|
||
if (t == RIGA_PRESTAZIONI) // Cerca il conto nella stringa di ricerca (solo per prestazioni)
|
||
{
|
||
TString16 tok;
|
||
// Scorre la stringa di ricerca ma solo per causale o CLI/FO
|
||
for (int i=0;good() && i<items;i++)
|
||
{
|
||
tok = _search_seq->get(i);
|
||
if (tok == "CF")
|
||
{
|
||
if (skip_clifo) continue;
|
||
gr = cli_file.get_int(CLI_GRUPPORIC);
|
||
co = cli_file.get_int(CLI_CONTORIC);
|
||
so = cli_file.get_long(CLI_SOTTOCRIC);
|
||
conto.set(gr,co,so);
|
||
if (conto.ok()) break;
|
||
}
|
||
else
|
||
if (tok == "CA")
|
||
{
|
||
CHECK(_caus,"Causale documento non valida");
|
||
if (_caus->IVA2bill(codiva,conto)) break;
|
||
}
|
||
}
|
||
}
|
||
|
||
static int __searching = false;
|
||
|
||
if (!conto.ok() && t == RIGA_SPESEDOC && !__searching)
|
||
{
|
||
if (spalma_spese())
|
||
{
|
||
amount_to_split += valore;
|
||
return _error;
|
||
}
|
||
const int rows = r.doc().physical_rows();
|
||
int row = -1;
|
||
|
||
for (int i = 1; row <0 && i <= rows; i++)
|
||
{
|
||
const char tipo = r.doc()[i].tipo().tipo();
|
||
|
||
if (tipo != RIGA_DESCRIZIONI && tipo != RIGA_SCONTI && tipo != RIGA_OMAGGI && tipo != RIGA_SPESEDOC)
|
||
row = i;
|
||
}
|
||
if (row > 0)
|
||
{
|
||
__searching = true;
|
||
search_costo_ricavo(conto, r.doc()[row], amount_to_split, valore);
|
||
__searching = false;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
break; // case 'P','S'
|
||
case 'C':
|
||
// righe sconti: vengono considerate in adjust_sconto_rows()
|
||
case 'D': // righe descrizioni (saltare)
|
||
default :
|
||
break;
|
||
} // end of switch
|
||
if (good())
|
||
{
|
||
if (!conto.ok() || !conto.find())
|
||
{
|
||
_conto_errato = conto;
|
||
_error = conto_error;
|
||
_nrow = r.get_int(RDOC_NRIGA);
|
||
}
|
||
}
|
||
return _error;
|
||
}
|
||
|
||
error_type TContabilizzazione::search_costo_ricavo_mat(TBill& conto, const TRiga_documento& r)
|
||
{
|
||
const char t = r.tipo().tipo();
|
||
switch (t)
|
||
{
|
||
case RIGA_OMAGGI: // righe omaggio come articoli spiaccicato identico (avranno imponibile 0)
|
||
case RIGA_MERCE: // righe di merce
|
||
{
|
||
TString16 key;
|
||
|
||
key.format("%03d%03d%06ld", conto.gruppo(), conto.conto(), conto.sottoconto());
|
||
const TRectype &t2 = cache().get("&CMT", key);
|
||
if (t2.empty())
|
||
{
|
||
key.format("%03d%03d", conto.gruppo(), conto.conto());
|
||
const TRectype &t1 = cache().get("&CMT", key);
|
||
if (t1.empty())
|
||
{
|
||
key.format("%03d", conto.gruppo());
|
||
const TRectype &t = cache().get("&CMT", key);
|
||
if (!t.empty())
|
||
conto.set(t.get_int("I0"), t.get_int("I1"), t.get_int("I2"));
|
||
}
|
||
else
|
||
conto.set(t1.get_int("I0"), t1.get_int("I1"), t1.get_int("I2"));
|
||
}
|
||
else
|
||
conto.set(t2.get_int("I0"), t2.get_int("I1"), t2.get_int("I2"));
|
||
}
|
||
break; // case 'M'
|
||
default :
|
||
break;
|
||
} // end of switch
|
||
return _error;
|
||
}
|
||
|
||
void TContabilizzazione::calculate_spese(const real& spese, real& sp_iva, int ndec, bool is_incasso, const TString& codiva_es, const TDocumento & doc)
|
||
{
|
||
const bool is_cli = doc.get_char(DOC_TIPOCF) != 'F';
|
||
const TBill& zio = is_incasso ? (is_cli ? _spin_billv : _spin_billa) : (is_cli ? _spbo_billv : _spbo_billa);
|
||
|
||
if (zio.ok())
|
||
{
|
||
TRiga_documento r((TDocumento *) &doc, "02"); // il tipo riga 02 spese a valore
|
||
r.put(RDOC_QTA, UNO);
|
||
r.put(RDOC_PREZZO, spese);
|
||
r.put(RDOC_CODIVA, codiva_es);
|
||
_righe_iva->add(r, zio, ndec);
|
||
sp_iva = r.imposta(false);
|
||
sp_iva.round(ndec);
|
||
if (doc.tipo().calcolo_lordo()) // Si ricorda che calcolo_lordo() e fattura_commerciale sono esclusivi.
|
||
{
|
||
// Totalizza per ogni codice iva il lordo
|
||
|
||
if (!_totali_lordi.is_key(codiva_es))
|
||
_totali_lordi.add(codiva_es, new real);
|
||
real& rl = (real&) _totali_lordi[codiva_es];
|
||
rl += spese + sp_iva;
|
||
}
|
||
}
|
||
else
|
||
_error = spinbo_error;
|
||
}
|
||
|
||
// Aggiunge le righe di spese incasso/bolli
|
||
error_type TContabilizzazione::add_spese_inbo(TDocumento& doc, const int ndec)
|
||
{
|
||
real tot_netto = doc.totale_netto();
|
||
|
||
// Aggiunge le spese d'incasso
|
||
real sp_incasso = doc.spese_incasso(tot_netto, ndec, _netto);
|
||
real iva_sp_incasso;
|
||
if (!sp_incasso.is_zero())
|
||
{
|
||
TString4 codiva_es; doc.iva_esente(codiva_es);
|
||
calculate_spese(sp_incasso,iva_sp_incasso,ndec,true,codiva_es.full() ? codiva_es : doc.codiva_spese(), doc);
|
||
}
|
||
|
||
const real rit = doc.ritenute();
|
||
tot_netto += sp_incasso + iva_sp_incasso - rit;
|
||
|
||
// Aggiunge le spese bolli
|
||
real sp_bolli = doc.bolli(tot_netto, ndec, _netto);
|
||
if (!sp_bolli.is_zero())
|
||
{
|
||
real iva_sp_bolli;
|
||
calculate_spese(sp_bolli, iva_sp_bolli, ndec, false, doc.codiva_bolli(), doc);
|
||
}
|
||
|
||
return _error;
|
||
}
|
||
|
||
// Aggiorna le righe di sconto (importo o a percentuale)
|
||
error_type TContabilizzazione::adjust_sconto_rows(TDocumento& doc)
|
||
{
|
||
if (!_sco_imp_bill.ok() || !_sco_perc_bill.ok())
|
||
{
|
||
_error = sconto_error;
|
||
return _error;
|
||
}
|
||
|
||
TAssoc_array aa = doc.tabella_iva(); // no reference
|
||
|
||
real sconto;
|
||
const int ndec = doc.decimals();
|
||
|
||
// Scorre tutti gli elementi della tabella IVA del documento (elementi per codice iva)
|
||
for (const TRiepilogo_iva* riep = (const TRiepilogo_iva*) aa.first_item();
|
||
riep != NULL; riep = (const TRiepilogo_iva*) aa.succ_item())
|
||
{
|
||
const TString4 cod = riep->cod_iva().codice(); // Codice IVA corrente
|
||
for (int i = 0; i < 2; i++) // Ciclo per sconto a percentuale (i == 0) e ad importo (i == 1)
|
||
{
|
||
//Importo sconto (sconto_perc() o sconto_imp())
|
||
//Calcola ::iva() sullo sconto
|
||
//Somma alla riga corrispondente o la crea se non esiste gia'
|
||
//I conti per aggiustare l'iva vengono fatti in adjust_iva_rows()
|
||
const bool perc = i == 0;
|
||
const TBill& conto = perc ? _sco_perc_bill : _sco_imp_bill;
|
||
sconto = perc ? -riep->sconto_perc() : -riep->sconto_imp();
|
||
if (sconto != ZERO)
|
||
{
|
||
TRiga_documento r(&doc, "07"); // il tipo riga 07 sconti
|
||
r.put(RDOC_QTA, UNO);
|
||
r.put(RDOC_PREZZO, sconto);
|
||
r.put(RDOC_CODIVA, cod);
|
||
_righe_iva->add(r, conto, ndec);
|
||
if (doc.tipo().calcolo_lordo()) // Si ricorda che calcolo_lordo() e fattura_commerciale() sono esclusivi.
|
||
{
|
||
// Totalizza per ogni codice iva il lordo
|
||
if (!_totali_lordi.is_key(cod))
|
||
_totali_lordi.add(cod, new real);
|
||
real& rl = (real&) _totali_lordi[cod];
|
||
rl -= sconto;
|
||
rl -= -riep->iva_sconto(); // Giochi strani sui segni :-)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return no_error;
|
||
}
|
||
|
||
static real inc_field(TRectype& rec, const char* field, const real& diff)
|
||
{
|
||
real val = rec.get_real(field);
|
||
val += diff;
|
||
rec.put(field, val);
|
||
return val;
|
||
}
|
||
|
||
// "Aggiusta" l'imposta sulle righe IVA secondo la tabella interna al documento
|
||
// Tratta anche i documenti in valuta. DI solito si tratta di poche lire.
|
||
error_type TContabilizzazione::adjust_iva_rows(TDocumento& doc)
|
||
{
|
||
TAssoc_array& aa = doc.tabella_iva();
|
||
TRiepilogo_iva * riep;
|
||
const int items = _movimento->iva_items();// Numero di righe IVA
|
||
const bool in_valuta = doc.in_valuta();
|
||
const bool calcolo_lordo = doc.tipo().calcolo_lordo();
|
||
real imponibile;
|
||
const int ndec = TCurrency::get_firm_dec(); // Numero di decimali della valuta di ditta
|
||
const TString4 codval(doc.get(DOC_CODVAL));
|
||
const real cambio = doc.cambio();
|
||
// Scorre tutti gli elementi della tabella IVA del documento (elementi per codice iva)
|
||
for (riep = (TRiepilogo_iva*) aa.first_item(); riep != NULL; riep = (TRiepilogo_iva*) aa.succ_item())
|
||
{
|
||
const TCodiceIVA & cod = riep->cod_iva(); // Codice IVA
|
||
const TString4 codiva(cod.codice());
|
||
real iva_g;
|
||
if (calcolo_lordo)
|
||
{
|
||
imponibile = _totali_lordi.is_key(codiva) ? (real&)_totali_lordi[codiva] : ZERO;
|
||
iva_g = cod.scorpora(imponibile, doc.decimals());
|
||
}
|
||
else
|
||
iva_g = riep->imposta();
|
||
|
||
if (in_valuta)
|
||
{
|
||
if (calcolo_lordo)
|
||
{
|
||
TCurrency_documento tot(imponibile + iva_g, doc);
|
||
tot.change_to_firm_val();
|
||
imponibile = tot.get_num();
|
||
iva_g = cod.scorpora(imponibile, ndec);
|
||
}
|
||
else
|
||
{
|
||
TCurrency_documento tot(riep->imponibile() + iva_g, doc);
|
||
tot.change_to_firm_val();
|
||
imponibile = tot.get_num();
|
||
iva_g = cod.scorpora(imponibile, ndec);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (ndec == 0)
|
||
{
|
||
TExchange cam(codval, cambio);
|
||
iva_g *= cam.get_change();
|
||
if (iva_g < ZERO)
|
||
iva_g.floor(0);
|
||
else
|
||
iva_g.ceil(0);
|
||
}
|
||
else
|
||
{
|
||
TCurrency_documento iva(iva_g);
|
||
iva.change_to_firm_val();
|
||
iva_g = iva.get_num();
|
||
}
|
||
}
|
||
|
||
TGeneric_distrib gd_iva(iva_g, ndec); // Instanzia il TGeneric_ditrib con la vera Imposta
|
||
TGeneric_distrib gd_imp(imponibile, ndec);
|
||
// Adesso scorre tutte le righe IVA contabili con questo codice IVA
|
||
int i;
|
||
|
||
for (i = 0; i < items; i++)
|
||
{
|
||
const TRectype& ie = _movimento->iva(i);
|
||
if (ie.get(RMI_CODIVA) == codiva) // Se il codice IVA e' uguale
|
||
{
|
||
gd_iva.add(ie.get_real(RMI_IMPOSTA)); // Aggiunge al TGeneric_distrib l'imposta corrente
|
||
if (calcolo_lordo || in_valuta)
|
||
gd_imp.add(ie.get_real(RMI_IMPONIBILE));
|
||
}
|
||
}
|
||
// Alla fine per performare tutto il calcolo (Thanx to TGeneric_distrib) si fanno le get
|
||
// E le si mettono nel rispettivo record IVA
|
||
|
||
for (i = 0; i < items; i++)
|
||
{
|
||
TRectype& ie = _movimento->iva(i);
|
||
if (ie.get(RMI_CODIVA) == codiva) // Se il codice IVA e' uguale
|
||
{
|
||
ie.put(RMI_IMPOSTA,gd_iva.get()); // Sostituisce l'imposta con quella ricalcolata al fine di avere tutto giusto
|
||
if (calcolo_lordo || in_valuta)
|
||
ie.put(RMI_IMPONIBILE, gd_imp.get());
|
||
}
|
||
}
|
||
} // Visto che vengono restituiti nello stesso ordine in cui sono state chiamate le rispettive TGeneric_distrib::add()
|
||
|
||
if (_caus->iva() == iva_acquisti && items > 0)
|
||
{
|
||
const TString16 tdoc_cont = doc.tipo().totale_doc_cont();
|
||
if (tdoc_cont.full())
|
||
{
|
||
real diffval = doc.get_real(tdoc_cont) - doc.totale_doc();
|
||
TCurrency_documento dv(diffval, doc);
|
||
dv.change_to_firm_val();
|
||
real difflit = dv.get_num();
|
||
if (!difflit.is_zero()) // Controlla se c'<27> differenza
|
||
{
|
||
TRectype& rigaiva = _movimento->iva(0);
|
||
|
||
const TCodiceIVA iva(rigaiva.get(RMI_CODIVA));
|
||
|
||
if (_caus->intra())
|
||
{
|
||
const real imponibile = inc_field(rigaiva, RMI_IMPONIBILE, difflit);
|
||
const real imposta = iva.imposta(imponibile);
|
||
rigaiva.put(RMI_IMPOSTA, imposta);
|
||
}
|
||
else
|
||
{
|
||
const real diffimp = iva.scorpora(difflit);
|
||
inc_field(rigaiva, RMI_IMPONIBILE, difflit);
|
||
inc_field(rigaiva, RMI_IMPOSTA, diffimp);
|
||
}
|
||
}
|
||
if (_caus->intra())
|
||
{
|
||
real ritfis;
|
||
for (int i = 0; i < items; i++)
|
||
ritfis += _movimento->iva(i).get_real(RMI_IMPOSTA);
|
||
_movimento->curr().put(MOV_RITFIS, ritfis);
|
||
}
|
||
}
|
||
}
|
||
|
||
return no_error;
|
||
}
|
||
|
||
error_type TContabilizzazione::create_iva_rows(TDocumento& doc)
|
||
{
|
||
const int items = _righe_iva->items();
|
||
const bool in_valuta = doc.in_valuta();
|
||
TRectype& head = _movimento->curr();
|
||
TToken_string key;
|
||
TString_array key_arr;
|
||
TString4 codiva;
|
||
TBill cur_conto;
|
||
char tipo;
|
||
int gruppo;
|
||
int conto;
|
||
long sottoconto;
|
||
const int annoes = head.get_int(MOV_ANNOES);
|
||
const long numreg = head.get_long(MOV_NUMREG);
|
||
real cambio = head.get_real(MOV_CAMBIO);
|
||
real imponibile,imposta;
|
||
const TString4 valuta(doc.valuta());
|
||
|
||
_righe_iva->get_keys(key_arr);
|
||
key_arr.sort();
|
||
|
||
for (int i = 0, nr = 0; i < items; i++)
|
||
{
|
||
key = key_arr.row(i);
|
||
const TRectype& cur = (const TRectype &)(*_righe_iva)[key];
|
||
codiva = cur.get(RMI_CODIVA);
|
||
tipo = cur.get_char(RMI_TIPOC);
|
||
gruppo = cur.get_int(RMI_GRUPPO);
|
||
conto = cur.get_int(RMI_CONTO);
|
||
sottoconto = cur.get_long(RMI_SOTTOCONTO);
|
||
cur_conto.set(gruppo, conto, sottoconto, tipo);
|
||
cur_conto.find();
|
||
|
||
imponibile = cur.get_real(RMI_IMPONIBILE);
|
||
imposta = cur.get_real(RMI_IMPOSTA);
|
||
|
||
if (in_valuta) // I documenti vanno sempre contabilizzati in Euro
|
||
{
|
||
TCurrency_documento imponval(imponibile, doc);
|
||
imponval.change_to_firm_val();
|
||
imponibile = imponval.get_num(); // imponibile in lire
|
||
TCurrency_documento impval(imposta, doc);
|
||
impval.change_to_firm_val();
|
||
imposta = impval.get_num(); // questa e' l'imposta ricalcolata
|
||
}
|
||
if (!imponibile.is_zero() && codiva.full())
|
||
{
|
||
TRectype& rec_iva = _movimento->iva(nr);
|
||
rec_iva.put(RMI_ANNOES,annoes);
|
||
rec_iva.put(RMI_NUMREG,numreg);
|
||
rec_iva.put(RMI_NUMRIG,nr+1); // La numerazione comincia da 1
|
||
rec_iva.put(RMI_CODIVA,codiva);
|
||
rec_iva.put(RMI_IMPONIBILE,imponibile);
|
||
rec_iva.put(RMI_IMPOSTA,imposta);
|
||
rec_iva.put(RMI_TIPOCR,cur_conto.tipo_cr());
|
||
rec_iva.put(RMI_INTRA, _caus->intra());
|
||
rec_iva.put(RMI_TIPOC, tipo);
|
||
rec_iva.put(RMI_GRUPPO, gruppo);
|
||
rec_iva.put(RMI_CONTO, conto);
|
||
rec_iva.put(RMI_SOTTOCONTO, sottoconto);
|
||
rec_iva.put(RMI_TIPODET, cur.get(RMI_TIPODET));
|
||
nr++;
|
||
}
|
||
}
|
||
return _error;
|
||
}
|
||
|
||
error_type TContabilizzazione::create_total_doc_row(TDocumento& doc)
|
||
// Crea la riga contabile di totale documento
|
||
{
|
||
TRectype& rec_cg = _movimento->cg(0);
|
||
TRectype& head = _movimento->curr();
|
||
const int annoes = head.get_int(MOV_ANNOES);
|
||
const long numreg = head.get_long(MOV_NUMREG);
|
||
const TDate datareg(head.get_date(MOV_DATAREG));
|
||
real totdoc(head.get_real(MOV_TOTDOC));
|
||
|
||
const TRectype& cli_file = _clifo->curr();
|
||
char tipocf = cli_file.get_char(CLI_TIPOCF);
|
||
long codcf = cli_file.get_long(CLI_CODCF);
|
||
int gruppo = 0, conto = 0;
|
||
|
||
TString16 catven(doc.get(DOC_CATVEN));
|
||
|
||
if (search_clifo_bill(catven) == no_error)
|
||
{
|
||
tipocf = _co_cliente.tipo();
|
||
gruppo = _co_cliente.gruppo();
|
||
conto = _co_cliente.conto();
|
||
codcf = _co_cliente.sottoconto();
|
||
}
|
||
else
|
||
{
|
||
_conto_errato = _co_cliente;
|
||
_error = contocf_error;
|
||
tipocf = _co_cliente.tipo();
|
||
gruppo = _co_cliente.gruppo();
|
||
conto = _co_cliente.conto();
|
||
codcf = _co_cliente.sottoconto();
|
||
_nrow = -1;
|
||
}
|
||
|
||
TConto contro;
|
||
if (_movimento->iva_items() > 0)
|
||
{
|
||
const TRectype& first_iva_row = _movimento->iva(0);
|
||
contro.get(first_iva_row);
|
||
}
|
||
|
||
rec_cg.put(RMV_ANNOES,annoes);rec_cg.put(RMV_NUMREG,numreg);
|
||
const char sezione = _caus->sezione(1);
|
||
rec_cg.put(RMV_NUMRIG,1); rec_cg.put(RMV_SEZIONE, sezione);
|
||
rec_cg.put(RMV_DATAREG,datareg); rec_cg.put(RMV_TIPOC,tipocf);
|
||
rec_cg.put(RMV_GRUPPO,gruppo);rec_cg.put(RMV_CONTO,conto);
|
||
rec_cg.put(RMV_SOTTOCONTO,codcf);
|
||
contro.put(rec_cg, true);
|
||
|
||
rec_cg.put(RMV_CUP, doc.get(DOC_CUP));
|
||
rec_cg.put(RMV_CIG, doc.get(DOC_CIG));
|
||
rec_cg.put(RMV_IMPORTO,totdoc); rec_cg.put(RMV_ROWTYPE,"T");
|
||
|
||
if (tipocf <= ' ')
|
||
{
|
||
head.zero(MOV_TIPO);
|
||
head.zero(MOV_CODCF);
|
||
}
|
||
|
||
return _error;
|
||
}
|
||
|
||
bool TContabilizzazione::valid_row_type(const char* rt) const
|
||
{
|
||
const TRectype& tri = cache().get("%TRI", rt);
|
||
return !tri.empty();
|
||
}
|
||
|
||
void TContabilizzazione::split_sp_amount(const real & amount, int decimals) const
|
||
{
|
||
TGeneric_distrib d(amount, decimals);
|
||
|
||
FOR_EACH_ASSOC_OBJECT((*_righe_iva), obj, key, itm)
|
||
{
|
||
const bool spese = key && *key == '3';
|
||
TRectype & r = (TRectype &)*itm;
|
||
|
||
const real imp = r.get_real(RMI_IMPONIBILE);
|
||
if (spese)
|
||
d.add(ZERO);
|
||
else
|
||
d.add(imp);
|
||
}
|
||
FOR_EACH_ASSOC_OBJECT((*_righe_iva), obj1, key1, itm1)
|
||
{
|
||
const bool spese = key1 && *key1 == '3';
|
||
TRectype & r = (TRectype &)*itm1;
|
||
|
||
if (spese)
|
||
d.get();
|
||
else
|
||
{
|
||
real imp = r.get_real(RMI_IMPONIBILE);
|
||
const TCodiceIVA i(r.get(RMI_CODIVA));
|
||
|
||
imp += d.get();
|
||
r.put(RMI_IMPONIBILE, imp);
|
||
real const imposta = i.imposta(imp);
|
||
r.put(RMI_IMPOSTA, imposta);
|
||
}
|
||
}
|
||
}
|
||
|
||
error_type TContabilizzazione::compile_rows_mov(TDocumento& doc)
|
||
// Compila le righe
|
||
{
|
||
TString4 tiporiga, codiva1, codiva2;
|
||
const int rows = doc.rows();
|
||
const int ndec = doc.decimals();
|
||
const bool fat_com = doc.tipo().fattura_commerciale();
|
||
|
||
real amount_to_split;
|
||
static TString_array tabella_ripartizione;
|
||
if (fat_com && tabella_ripartizione.empty())
|
||
{
|
||
TConfig cnf(CONFIG_STUDIO, "ve");
|
||
for (int k = 1; k <= MAX_IVA_SLICES; k++)
|
||
{
|
||
TToken_string* tt = new TToken_string();
|
||
tt->add(cnf.get("EXCLUDE_PERC", "ve", k));
|
||
tt->add(cnf.get("EXCLUDE_IVA", "ve", k));
|
||
tabella_ripartizione.add(tt);
|
||
}
|
||
}
|
||
|
||
_righe_iva->destroy(); // resetta l'assoc_array delle righe di iva
|
||
_totali_lordi.destroy();// resetta l'assoc_array dei totali lordi
|
||
|
||
const TString16 fldvalmat = ini_get_string(CONFIG_DITTA, "ve", "FldValMat", "");
|
||
|
||
for (int i=1; good() && i<=rows; i++) // browse all this fucked document rows
|
||
{
|
||
TRiga_documento& r = doc[i];
|
||
const TString4 tiporiga = r.get(RDOC_TIPORIGA);
|
||
if (valid_row_type(tiporiga)) // controlla l'esistenza della riga
|
||
{
|
||
TBill conto, contomat;
|
||
real pricemat;
|
||
const char tipo = r.tipo().tipo();
|
||
// Le righe omaggio senza addebito IVA vanno saltate
|
||
const bool riga_omaggio = tipo == RIGA_OMAGGI && r.get_bool(RDOC_ADDIVA);
|
||
if ((tipo != RIGA_DESCRIZIONI && tipo != RIGA_SCONTI && tipo != RIGA_RETTIFICHE) || riga_omaggio)
|
||
{
|
||
const bool spesa = r.tipo().tipo() == RIGA_SPESEDOC;
|
||
char tipo_rit = '\0';
|
||
if (spesa)
|
||
tipo_rit = r.spesa().tipo_ritenuta();
|
||
|
||
const bool ritenuta = tipo_rit != '\0' && !_caus->intra();
|
||
|
||
TBill conto;
|
||
if (!ritenuta)
|
||
{
|
||
if (!riga_omaggio && r.imponibile().is_zero())
|
||
continue;
|
||
search_costo_ricavo(conto, r, amount_to_split, r.imponibile()); // l'errore eventuale viene settato qui dentro
|
||
|
||
if (good() && fldvalmat.full())
|
||
{
|
||
pricemat = real(cache().get(LF_ANAMAG, r.get(RDOC_CODARTMAG), fldvalmat));
|
||
if (!pricemat.is_zero())
|
||
{
|
||
contomat = conto;
|
||
search_costo_ricavo_mat(contomat, r); // l'errore eventuale viene settato qui dentro
|
||
}
|
||
}
|
||
}
|
||
if (good())
|
||
{
|
||
if (fat_com)
|
||
{
|
||
const TString4 codiva2 = r.get(RDOC_CODIVA); // Save...
|
||
for (int j=0; j < MAX_IVA_SLICES; j++)
|
||
{
|
||
const real perc = real(tabella_ripartizione.row(j).get(0)) / CENTO;
|
||
codiva1 = tabella_ripartizione.row(j).get(1);
|
||
if (perc == ZERO || codiva1.blank())
|
||
continue;
|
||
|
||
r.put(RDOC_CODIVA, codiva1);
|
||
if (riga_omaggio)
|
||
{
|
||
_error = _righe_iva->add_omaggi(r, conto, ALL_DECIMALS, perc);
|
||
if (_error != no_error)
|
||
_nrow = i;
|
||
}
|
||
else
|
||
_righe_iva->add(r, conto, ALL_DECIMALS, perc);
|
||
}
|
||
r.put(RDOC_CODIVA, codiva2); //Restore
|
||
}
|
||
else
|
||
{
|
||
if (ritenuta)
|
||
{
|
||
TCurrency_documento c(r.ritenuta(tipo_rit));
|
||
TBill cnt; _caus->bill(tipo_rit == 'F' ? RIGA_RITENUTE_FISCALI : RIGA_RITENUTE_SOCIALI, cnt);
|
||
|
||
if (cnt.ok())
|
||
{
|
||
TRectype & h = _movimento->lfile().curr();
|
||
real val;
|
||
if (r.doc().in_valuta())
|
||
{
|
||
val = h.get_real(MOV_TOTDOCVAL) - c.get_num();
|
||
h.put(MOV_TOTDOCVAL, val);
|
||
}
|
||
c.change_to_firm_val();
|
||
val = h.get_real(MOV_TOTDOC) - c.get_num();
|
||
h.put(MOV_TOTDOC, val);
|
||
|
||
const char * campo = tipo_rit == 'F' ? MOV_RITFIS : MOV_RITSOC;
|
||
|
||
val = h.get_real(campo) + c.get_num();
|
||
h.put(campo, val);
|
||
}
|
||
}
|
||
else
|
||
if (riga_omaggio)
|
||
{
|
||
_error = _righe_iva->add_omaggi(r, conto);
|
||
if (_error != no_error)
|
||
_nrow = i;
|
||
}
|
||
else
|
||
{
|
||
if (contomat.ok() && contomat != conto && pricemat != 0)
|
||
{
|
||
TRiga_documento rlav(r);
|
||
TRiga_documento rmat(r);
|
||
const real prezzo = r.get_real(RDOC_PREZZO);
|
||
rmat.put(RDOC_PREZZO, pricemat);
|
||
rmat.zero(RDOC_SCONTO);
|
||
const real valmat = rmat.imponibile();
|
||
const real diff = r.imponibile() - valmat;
|
||
|
||
rlav.put(RDOC_PREZZO, diff);
|
||
rlav.put(RDOC_QTA, 1);
|
||
rlav.zero(RDOC_SCONTO);
|
||
rmat.put(RDOC_PREZZO, valmat);
|
||
rmat.put(RDOC_QTA, 1);
|
||
rmat.zero(RDOC_SCONTO);
|
||
_righe_iva->add(rlav, conto);
|
||
_righe_iva->add(rmat, contomat);
|
||
}
|
||
else
|
||
if (conto.ok())
|
||
_righe_iva->add(r, conto);
|
||
}
|
||
|
||
if (!ritenuta && r.doc().tipo().calcolo_lordo()) // Si ricorda che calcolo_lordo() e fattura_commerciale() sono esclusivi.
|
||
{
|
||
// Totalizza per ogni codice iva il lordo
|
||
const TString& cod = r.get(RDOC_CODIVA);
|
||
if (!_totali_lordi.is_key(cod))
|
||
_totali_lordi.add(cod, new real);
|
||
real& rl = (real&) _totali_lordi[cod];
|
||
rl += r.imponibile(true);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
_error = row_type_error;
|
||
_nrow = i;
|
||
}
|
||
|
||
}
|
||
|
||
if (!amount_to_split.is_zero())
|
||
split_sp_amount(amount_to_split, ndec);
|
||
|
||
// Non ammette assenza righe IVA
|
||
if (good() && _righe_iva->empty())
|
||
_error = no_rows_error;
|
||
|
||
// Crea le righe per le spese d'incasso e bolli
|
||
if (good())
|
||
add_spese_inbo(doc, doc.decimals());
|
||
|
||
// Aggiorna le righe di sconto (sconto ad importo o percentuale)
|
||
if (good())
|
||
adjust_sconto_rows(doc);
|
||
|
||
// Crea le righe di IVA
|
||
if (good())
|
||
create_iva_rows(doc);
|
||
|
||
// Controlla che le imposte per ogni aliquota ed eventualmente corregge le imposte stesse sulle righe
|
||
if (good())
|
||
adjust_iva_rows(doc);
|
||
|
||
// Crea la riga di totale documento
|
||
if (good())
|
||
create_total_doc_row(doc);
|
||
// crea le righe di contabilita'
|
||
if (good())
|
||
{
|
||
const TString descr_cr = doc.clifor().get(CLI_RAGSOC); // Probabile porcata ... che Pharmatex non vuole!
|
||
switch (_movimento->recalc_cg_rows(descr_cr, *_caus))
|
||
{
|
||
case 1 : _error = movement_error; break;
|
||
case 2 : _error = cau_ritintra_error; break;
|
||
default: break;
|
||
}
|
||
}
|
||
|
||
const TRegistro& registro = _caus->reg();
|
||
const bool iva_mov = registro.ok();
|
||
if (!iva_mov)
|
||
{
|
||
const bool check_sez = ini_get_bool(CONFIG_DITTA, "ve", "CHECK_SEZ");
|
||
bool swap = false;
|
||
if (check_sez)
|
||
{
|
||
const TString4 sz = _movimento->cg(0).get(RMV_SEZIONE);
|
||
for (int row = 1; !swap && row <= doc.physical_rows(); row++)
|
||
{
|
||
const TRiga_documento& r = doc[row];
|
||
if (r.is_spese())
|
||
{
|
||
const TSpesa_prest s(r.get(RDOC_CODART));
|
||
const TString& sez = s.get("S11");
|
||
swap = sez == sz;
|
||
}
|
||
}
|
||
}
|
||
|
||
const int cgitems = _movimento->cg_items();
|
||
for (int i = cgitems-1; i >= 0; i--)
|
||
{
|
||
TRectype& rec_cg = _movimento->cg(i);
|
||
rec_cg.zero(RMV_ROWTYPE);
|
||
if (check_sez && swap)
|
||
{
|
||
const char sez = rec_cg.get_char(RMV_SEZIONE);
|
||
rec_cg.put(RMV_SEZIONE, sez == 'D' ? 'A' : 'D');
|
||
}
|
||
}
|
||
_movimento->destroy_iva_row();
|
||
}
|
||
return _error;
|
||
}
|
||
|
||
// Compila le righe
|
||
error_type TContabilizzazione::compile_rows_mov_re(TDocumento& doc)
|
||
{
|
||
const int rows = doc.rows();
|
||
const int ndec = doc.decimals();
|
||
real amount_to_split;
|
||
|
||
_righe_iva->destroy(); // resetta l'assoc_array delle righe di iva
|
||
for (int i=1; good() && i<=rows; i++) // browse all this fucked document rows
|
||
{
|
||
const TRiga_documento& r = doc[i];
|
||
const TString4 tiporiga = r.get(RDOC_TIPORIGA);
|
||
if (valid_row_type(tiporiga)) // controlla l'esistenza della riga
|
||
{
|
||
const char tipo = r.tipo().tipo();
|
||
// Le righe omaggio senza addebito IVA vanno saltate
|
||
const bool riga_omaggio = tipo == RIGA_OMAGGI && r.get_bool(RDOC_ADDIVA);
|
||
const bool spesa = r.tipo().tipo() == RIGA_SPESEDOC;
|
||
|
||
if ((tipo != RIGA_DESCRIZIONI && tipo != RIGA_SCONTI && tipo != RIGA_RETTIFICHE) && !riga_omaggio)
|
||
{
|
||
TBill conto;
|
||
search_costo_ricavo(conto, r, amount_to_split, r.imponibile()); // l'errore eventuale viene settato qui dentro
|
||
if (good())
|
||
_righe_iva->add(r, conto);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
_error = row_type_error;
|
||
_nrow = i;
|
||
}
|
||
|
||
}
|
||
split_sp_amount(amount_to_split, ndec);
|
||
|
||
if (good() && _righe_iva->empty())
|
||
_error = no_rows_error;
|
||
|
||
// Crea le righe per le spese d'incasso e bolli
|
||
if (good())
|
||
add_spese_inbo(doc,ndec);
|
||
|
||
// Crea le righe di IVA
|
||
if (good())
|
||
create_iva_rows(doc);
|
||
|
||
// Aggiorna le righe di sconto (sconto ad importo o percentuale)
|
||
if (good())
|
||
adjust_sconto_rows(doc);
|
||
|
||
if (good())
|
||
adjust_iva_rows(doc);
|
||
|
||
// Crea la riga di totale documento
|
||
if (good())
|
||
{
|
||
int righe = _movimento->iva_items();
|
||
for (int i=0; i<righe; i++)
|
||
_movimento->add_row_re(i);
|
||
righe = _movimento->cg_items();
|
||
int row_to_add = righe - 1;
|
||
for (int j = row_to_add; j >= 0; j--)
|
||
if (!_movimento->add_row_cp_re(row_to_add))
|
||
row_to_add--;
|
||
}
|
||
_movimento->destroy_iva_row();
|
||
return _error;
|
||
}
|
||
|
||
error_type TContabilizzazione::change_doc_status(TDocumento& doc)
|
||
// Cambia lo stato del documento
|
||
{
|
||
doc.stato(get_char("S4"));
|
||
if (doc.rewrite() != NOERR)
|
||
_error = chg_stat_error;
|
||
return _error;
|
||
}
|
||
|
||
error_type TContabilizzazione::write_scadenze(TDocumento& doc, bool recontabilizing)
|
||
// Scrive le scadenze. Liberamente tratto da cg2104.cpp.
|
||
{
|
||
const TRectype& head = _movimento->curr();
|
||
if (head.get_real(MOV_TOTDOC).is_zero())
|
||
return _error;
|
||
|
||
const bool is_nc = doc.is_nota_credito();
|
||
const long nreg = head.get_long(MOV_NUMREG);
|
||
|
||
if (recontabilizing)
|
||
{
|
||
TPartite_array pa; pa.add_numreg(nreg);
|
||
bool dirty = false;
|
||
for (TPartita* game = pa.first(); game; game = pa.next())
|
||
{
|
||
if (game->conto() != _co_cliente)
|
||
{
|
||
const int rf = game->first();
|
||
if (game->last() > rf)
|
||
return _error = scadenze_error;
|
||
else
|
||
{
|
||
game->rimuovi_riga(rf);
|
||
dirty = true;
|
||
}
|
||
}
|
||
}
|
||
if (dirty)
|
||
pa.rewrite();
|
||
}
|
||
|
||
int anno = head.get_int(MOV_ANNOIVA);
|
||
TString8 numpart; // Max. 7 chars
|
||
if (_nump_cfg)
|
||
{
|
||
numpart = head.get(MOV_PROTIVA);
|
||
if (is_nc)
|
||
{
|
||
int annorif = doc.get_int("ANNORIF");
|
||
if (annorif <= 0)
|
||
{
|
||
const TDate ddr = doc.get_date(DOC_DATADOCRIF);
|
||
annorif = ddr.year();
|
||
if (annorif <= 0)
|
||
annorif = anno;
|
||
}
|
||
TString4 codnumrif = doc.get("CODNUMRIF");
|
||
if (codnumrif.blank())
|
||
codnumrif = doc.get(DOC_CODNUM);
|
||
|
||
const TString8 numdocrif = doc.get(DOC_NUMDOCRIF);
|
||
|
||
if (numdocrif.full())
|
||
{
|
||
TToken_string keydoc;
|
||
keydoc.add(doc.get(DOC_PROVV));
|
||
keydoc.add(annorif);
|
||
keydoc.add(codnumrif);
|
||
keydoc.add(numdocrif);
|
||
const long numreg = atol(cache().get(LF_DOC, keydoc, DOC_NUMREG));
|
||
if (numreg > 0)
|
||
{
|
||
TPartite_array pa; pa.add_numreg(numreg);
|
||
const TPartita* game = pa.first();
|
||
if (game != NULL)
|
||
{
|
||
anno = game->anno();
|
||
numpart = game->numero();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
numpart = doc.get(DOC_NUMDOCRIF);
|
||
if (_caus->iva() == iva_vendite && !is_nc)
|
||
numpart.cut(0);
|
||
|
||
if (numpart.blank())
|
||
numpart = head.get(MOV_NUMDOC);
|
||
else
|
||
{
|
||
const TDate ddr = doc.get_date(DOC_DATADOCRIF);
|
||
if (ddr.ok())
|
||
anno = ddr.year();
|
||
}
|
||
}
|
||
|
||
TPartita* newgame = NULL;
|
||
if (anno > 0 && numpart.full())
|
||
{
|
||
const tipo_movimento tmov = _caus->tipomov();
|
||
const TString80 desc(head.get(MOV_DESCR));
|
||
const TString4 codcaus(_caus->codice());
|
||
const TString4 v(head.get(MOV_CODVAL));
|
||
const TDate d(head.get_date(MOV_DATACAM));
|
||
const real c(head.get_real(MOV_CAMBIO));
|
||
const TValuta cambio(v, d, c); // verificare
|
||
const TString8 agente(doc.get(DOC_CODAG));
|
||
const int ndec = doc.decimals();
|
||
const char sezione = _movimento->cg(0).get_char(RMV_SEZIONE); // Dare/Avere
|
||
|
||
newgame = new TPartita(_co_cliente, anno, numpart);
|
||
newgame->allinea(); // Rispettare sempre l'allineamento del numero partita!
|
||
|
||
int row = 0;
|
||
if (tmov == tm_fattura)
|
||
row = newgame->prima_fattura(nreg); // Riga fattura di questo movimento
|
||
else
|
||
row = newgame->prima_riga(nreg, tmov); // Riga nc di questo movimento
|
||
TRiga_partite& partita = row <= 0 ? newgame->new_row() : newgame->riga(row);
|
||
const int nuova_riga = partita.get_int(PART_NRIGA);
|
||
|
||
// put data on partita
|
||
partita.put(PART_TIPOMOV, tmov);
|
||
partita.put(PART_NREG, nreg); // Riferimento alla registrazione contabile
|
||
partita.put(PART_NUMRIG, 1); // Riferimento alla riga contabile del totale
|
||
partita.put(PART_DATAREG, head.get(MOV_DATAREG));
|
||
partita.put(PART_DATADOC, head.get(MOV_DATADOC));
|
||
partita.put(PART_NUMDOC, head.get(MOV_NUMDOC));
|
||
partita.put(PART_DESCR, desc);
|
||
partita.put(PART_CODCAUS, codcaus);
|
||
partita.put(PART_REG, _caus->reg().name());
|
||
partita.put(PART_PROTIVA, head.get(MOV_PROTIVA));
|
||
partita.put(PART_SEZ, sezione);
|
||
|
||
const real totdoc(head.get(MOV_TOTDOC));
|
||
const real totdocval(head.get(MOV_TOTDOCVAL));
|
||
const bool in_valuta = cambio.in_valuta();
|
||
const bool swapped = !in_valuta && test_swap();
|
||
const TCurrency_documento td((in_valuta ? totdocval : totdoc) * (swapped ? -1 : 1), doc);
|
||
|
||
partita.put(PART_IMPTOTDOC, totdoc);
|
||
|
||
cambio.put(partita);
|
||
if (in_valuta)
|
||
partita.put(PART_IMPTOTVAL,totdocval);
|
||
|
||
if (partita.is_fattura())
|
||
{
|
||
TPagamento& pag = doc.pagamento();
|
||
const TCurrency_documento totspese(doc.spese(), doc);
|
||
TCurrency_documento totimposte(doc.imposta(true), doc);
|
||
|
||
real imposte;
|
||
for (int j = _movimento->iva_items()-1; j >= 0; j--)
|
||
imposte += _movimento->iva(j).get_real(RMI_IMPOSTA) * (swapped ? -1 : 1);
|
||
if (_caus->iva() == iva_acquisti) // Ricalcola precisamente il totale imposte
|
||
{
|
||
real ti = imposte;
|
||
if (in_valuta)
|
||
cambio.eur2val(ti);
|
||
totimposte.set_num(ti);
|
||
}
|
||
|
||
const TCurrency totimponibili = td - totimposte - totspese;
|
||
TCurrency_documento anticipo(doc.get_real(DOC_IMPPAGATO), doc);
|
||
|
||
// Caso normale: anticipo inferiore all'intera cifra da pagare
|
||
if (anticipo.abs() < td.abs())
|
||
{
|
||
const real imposte_effettive = is_split_payment(head) ? ZERO : totimposte.get_num();
|
||
|
||
TGeneric_distrib d(anticipo.get_num(), ndec);
|
||
d.add(totimponibili.get_num());
|
||
d.add(imposte_effettive);
|
||
d.add(totspese.get_num());
|
||
|
||
const TCurrency_documento pagtotimponibili(totimponibili.get_num() - d.get(), doc);
|
||
TCurrency_documento diffiva(d.get(), doc);
|
||
const TCurrency_documento pagtotimposte (imposte_effettive - diffiva.get_num(), doc);
|
||
const TCurrency_documento pagtotspese (totspese.get_num() - d.get(), doc);
|
||
|
||
if (in_valuta)
|
||
{
|
||
const real change = cambio.cambio();
|
||
//real val1 = totimponibili * change;
|
||
TCurrency val2(imposte); diffiva.change_to_firm_val(); val2 -= diffiva;
|
||
TCurrency_documento val3(pagtotspese); val3.change_to_firm_val();
|
||
TCurrency val1(totdoc);
|
||
TCurrency_documento ant(anticipo.get_num(), doc);
|
||
ant.change_to_firm_val();
|
||
val1 -= ant + val2 + val3;
|
||
if (test_swap())
|
||
{
|
||
val1 = -val1;
|
||
val2 = -val2;
|
||
val3 = -val3;
|
||
}
|
||
// Cosi' corregge eventuali scompensi di poche lirette
|
||
pag.set_total_valuta(pagtotimponibili, pagtotimposte, pagtotspese, val1, val2, val3);
|
||
}
|
||
else
|
||
{
|
||
pag.set_total(pagtotimponibili, pagtotimposte, pagtotspese);
|
||
}
|
||
pag.set_rate_auto();
|
||
}
|
||
else
|
||
pag.zap_rate();
|
||
|
||
if (!anticipo.is_zero())
|
||
{
|
||
pag.add_rata();
|
||
|
||
TDate first_date(doc.data());
|
||
TDate first_scad(pag.data_rata(0));
|
||
|
||
if (first_date == first_scad)
|
||
pag.set_datarata(0, ++first_scad); // Sposta in avanti la data della prima scadenza di un giorno.
|
||
|
||
// Shift delle rate verso il basso
|
||
for (int k=pag.n_rate()-1; k>0; k--)
|
||
pag.rata(k) = pag.rata(k-1);
|
||
|
||
// Sostituisce la prima rata con quella dell'anticipo
|
||
|
||
// Se l'anticipo <20> pi<70> grande del totale, si crea una riga di scadenza
|
||
// con l'importo del totale doc.
|
||
if (anticipo.abs() >= td.abs())
|
||
anticipo = td;
|
||
|
||
TCurrency_documento anticipo_base(anticipo); anticipo_base.change_to_firm_val();
|
||
|
||
// Crea una rimessa diretta con la data del documento per il valore dell'anticipo
|
||
pag.set_rata(0, in_valuta ? anticipo.get_num() : ZERO, anticipo_base.get_num(), first_date, 1, "", false);
|
||
}
|
||
|
||
const int nr = pag.n_rate();
|
||
|
||
real imponibile, imponibile_val;
|
||
for (int i = nr-1; i >= 0; i--)
|
||
{
|
||
if (in_valuta)
|
||
imponibile_val += pag.tval_rata(i);
|
||
imponibile += pag.tlit_rata(i);
|
||
}
|
||
|
||
partita.put(PART_IMPORTO, imponibile);
|
||
partita.put(PART_IMPORTOVAL, in_valuta ? imponibile_val : ZERO);
|
||
partita.put(PART_IMPOSTA, pag.imposta(in_valuta));
|
||
partita.put(PART_SPESE, totspese.get_num());
|
||
|
||
// Se sto ricontabilizzando meno rate di quante esistevano prima!
|
||
if (nr < partita.rate())
|
||
{
|
||
// Collega eventuali pagamenti. Smpre meglio che perderli
|
||
newgame->scollega_pagamenti(nuova_riga, nr+1);
|
||
// Elimina tutte le rate in eccesso
|
||
for (int i = partita.rate(); i > nr; i--)
|
||
partita.elimina_rata(i);
|
||
}
|
||
|
||
const TString8 abipr = doc.get(DOC_CODABIP), cabpr = doc.get(DOC_CODCABP),
|
||
abi = doc.get(DOC_CODABIA), cab = doc.get(DOC_CODCABA);
|
||
const TString4 codpag = head.get(MOV_CODPAG);
|
||
|
||
for (int i = 0; i < nr; i++)
|
||
{
|
||
TRiga_scadenze* prs = i < partita.rate() ? &partita.rata(i+1) : &partita.new_row(i+1);
|
||
TRiga_scadenze& scadenza = *prs;
|
||
|
||
scadenza.put(SCAD_CODPAG, codpag); // Codice pagamento
|
||
scadenza.put(SCAD_CODAG, agente); // Codice agente
|
||
|
||
scadenza.put(SCAD_DATASCAD, pag.data_rata(i)); // Data scadenza
|
||
scadenza.put(SCAD_IMPORTO, pag.tlit_rata(i)); // Importo
|
||
if (in_valuta)
|
||
scadenza.put(SCAD_IMPORTOVAL, pag.tval_rata(i)); // Importo in valuta
|
||
scadenza.put(SCAD_TIPOPAG, pag.tipo_rata(i)); // Tipo pagamento
|
||
scadenza.put(SCAD_ULTCLASS, pag.ulc_rata(i)); // Ulteriore classificazione
|
||
scadenza.put(SCAD_CODABIPR, abipr); // Ns ABI
|
||
scadenza.put(SCAD_CODCABPR, cabpr); // Ns CAB
|
||
scadenza.put(SCAD_CODABI, abi); // Vs ABI
|
||
scadenza.put(SCAD_CODCAB, cab); // Vs CAB
|
||
// scadenza.put(SCAD_DESCR, ????); // Note
|
||
}
|
||
} // if fattura
|
||
else if (is_nc)
|
||
{
|
||
TImporto residuoval(sezione, doc.totale_doc());
|
||
TImporto residuolit(sezione, abs(totdoc));
|
||
|
||
partita.put(PART_DATAPAG, doc.get(DOC_DATADOC));
|
||
partita.put(PART_TIPOPAG, doc.pagamento().tipo_rata(0));
|
||
|
||
// Attenzione: le note di credito possono avere in testata valori negativi! Qui vanno positivi.
|
||
partita.put(PART_IMPTOTDOC, abs(totdoc));
|
||
partita.put(PART_IMPTOTVAL, abs(totdocval));
|
||
|
||
// Attenzione: l'importo giusto viene poi aggiornato dalla modifica pagamento
|
||
partita.zero(PART_IMPORTO);
|
||
partita.zero(PART_IMPORTOVAL);
|
||
|
||
const TDate datadocrif = doc.get_date(DOC_DATADOCRIF);
|
||
const TString16 numdocrif = doc.get(DOC_NUMDOCRIF);
|
||
int p;
|
||
|
||
for (p = newgame->prima_fattura(); p > 0 && p < nuova_riga; p++)
|
||
{
|
||
const TRiga_partite& fatt = newgame->riga(p);
|
||
const TDate datadoc = fatt.get_date(PART_DATADOC);
|
||
const TString8 numdoc = fatt.get(PART_NUMDOC);
|
||
if (datadoc.year() == datadocrif.year() && numdoc == numdocrif)
|
||
break;
|
||
}
|
||
if (p > 0 && p < nuova_riga)
|
||
{
|
||
TPagamento& pag = doc.pagamento();
|
||
|
||
TCurrency_documento totdoc(abs(doc.totale_doc()), doc);
|
||
TCurrency_documento totspese(abs(doc.spese()), doc);
|
||
TCurrency_documento totimposte(abs(doc.imposta(true)), doc);
|
||
TCurrency_documento totimponibili = totdoc - totspese - totimposte;
|
||
if (in_valuta)
|
||
{
|
||
TCurrency_documento val2(totimposte); val2.change_to_firm_val();
|
||
TCurrency_documento val3(totspese); val3.change_to_firm_val();
|
||
TCurrency_documento val1(totdoc); val1.change_to_firm_val(); val1 -= val2+val3;
|
||
// Cosi' corregge eventuali scompensi di poche lirette
|
||
pag.set_total_valuta(totimponibili, totimposte, totspese, val1, val2, val3);
|
||
}
|
||
else
|
||
pag.set_total(totimponibili, totimposte, totspese);
|
||
pag.set_rate_auto();
|
||
|
||
const TRiga_partite& fatt = newgame->riga(p);
|
||
for (int r = 1; r <= fatt.rate() && r <= pag.n_rate(); r++)
|
||
{
|
||
const TRiga_scadenze& rata = fatt.rata(r);
|
||
const real imprata = rata.residuo(false).valore();
|
||
const real imprataval = rata.residuo(true).valore();
|
||
real importo_rata_lit = pag.importo_rata(r-1, false);
|
||
real importo_rata_val = in_valuta ? pag.importo_rata(r-1, true) : importo_rata_lit;
|
||
real delta_lit = importo_rata_lit - imprata;
|
||
real delta_val = in_valuta ? importo_rata_val - imprataval : ZERO;
|
||
// Controlla se l'importo della nota di credito supera quello della fattura
|
||
if (delta_lit > ZERO || delta_val > ZERO)
|
||
{
|
||
// Detrae l'eccedenza dalla rata corrente e la sposta nella rata successiva
|
||
importo_rata_lit -= delta_lit;
|
||
importo_rata_val -= delta_val;
|
||
|
||
if (r == pag.n_rate())
|
||
{
|
||
// Crea eventuale ultima rata mancante
|
||
pag.add_rata();
|
||
}
|
||
else
|
||
{
|
||
// Incrementa importo rata
|
||
delta_lit += pag.importo_rata(r, false);
|
||
delta_val += pag.importo_rata(r, true);
|
||
}
|
||
const TDate oggi(TODAY);
|
||
const int tiporata = pag.tipo_rata(r-1);
|
||
pag.set_rata(r, delta_val, delta_lit, oggi, tiporata, "", false);
|
||
}
|
||
if (!importo_rata_lit.is_zero() || (in_valuta && !importo_rata_val.is_zero()))
|
||
{
|
||
TRectype pag = newgame->pagamento(p, r, nuova_riga);
|
||
pag.put(PAGSCA_IMPORTO, importo_rata_lit);
|
||
if (in_valuta)
|
||
{
|
||
pag.put(PAGSCA_IMPORTOVAL, importo_rata_val);
|
||
residuoval -= TImporto(sezione, importo_rata_val);
|
||
}
|
||
else
|
||
residuoval -= TImporto(sezione, importo_rata_lit);
|
||
residuolit -= TImporto(sezione, importo_rata_lit);
|
||
|
||
pag.put(PAGSCA_ACCSAL, "A");
|
||
newgame->modifica_pagamento(pag, cambio, true);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (!residuoval.is_zero())
|
||
{
|
||
// Pagamento non assegnato
|
||
TRectype unpag = newgame->pagamento(TPartita::UNASSIGNED, 0, nuova_riga);
|
||
if (in_valuta)
|
||
{
|
||
unpag.put(PAGSCA_IMPORTOVAL, residuoval.valore());
|
||
unpag.put(PAGSCA_IMPORTO, residuolit.valore());
|
||
}
|
||
else
|
||
unpag.put(PAGSCA_IMPORTO, residuoval.valore());
|
||
unpag.put(PAGSCA_ACCSAL, "A");
|
||
newgame->modifica_pagamento(unpag, cambio, true);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (newgame != NULL) // Se non ho cancellato il numero partita ...
|
||
{
|
||
if (!newgame->write()) // Salva nuova partita
|
||
_error = write_part_error;
|
||
delete newgame;
|
||
}
|
||
|
||
return _error;
|
||
}
|
||
|
||
static void rec2ini(const TRectype& rec, TConfig& ini)
|
||
{
|
||
for (int i = 0; i < rec.items(); i++)
|
||
{
|
||
const char* fname = rec.fieldname(i);
|
||
const TString& val = rec.get(fname);
|
||
if (val.full())
|
||
{
|
||
if (val.find(' ') >= 0 && rec.type(fname) == _alfafld)
|
||
{
|
||
TString quoted; quoted << '"' << val << '"';
|
||
ini.set(fname, quoted);
|
||
}
|
||
else
|
||
ini.set(fname, val);
|
||
}
|
||
}
|
||
}
|
||
|
||
bool TContabilizzazione::dispatch_transaction(TMovimentoPN& movimento, const char* action) const
|
||
{
|
||
const TRectype& head = movimento.curr();
|
||
bool done = ::can_dispatch_transaction(head);
|
||
if (!done)
|
||
return false;
|
||
|
||
TFilename tmpini; tmpini.temp("cnt", "ini");
|
||
|
||
if (done) // dummy test
|
||
{
|
||
TConfig ini(tmpini, "Transaction");
|
||
ini.set("Firm", prefix().get_codditta(), "Transaction");
|
||
ini.set("User", user());
|
||
ini.set("HostName", get_hostname());
|
||
ini.set("Action", action);
|
||
ini.set("Mode", "Auto");
|
||
int year, release, tag, patch;
|
||
if (TApplication::get_version_info(year, release, tag, patch))
|
||
{
|
||
TString80 ver;
|
||
ver.format("%d %d.%d-%d", year, release, tag, patch);
|
||
ini.set("Version", ver);
|
||
}
|
||
|
||
TString16 para; para << head.num();
|
||
ini.set_paragraph(para);
|
||
rec2ini(head, ini);
|
||
|
||
for (int i = 0; i < movimento.cg_items(); i++)
|
||
{
|
||
para.format("%d,%d", LF_RMOV, i+1);
|
||
ini.set_paragraph(para);
|
||
rec2ini(movimento.cg(i), ini);
|
||
}
|
||
for (int i = 0; i < movimento.iva_items(); i++)
|
||
{
|
||
para.format("%d,%d", LF_RMOVIVA, i+1);
|
||
ini.set_paragraph(para);
|
||
rec2ini(movimento.iva(i), ini);
|
||
}
|
||
}
|
||
|
||
done = ::dispatch_transaction(head, tmpini);
|
||
tmpini.fremove();
|
||
|
||
return done;
|
||
}
|
||
|
||
error_type TContabilizzazione::write_all(TDocumento& doc, TMovimentoPN_VE & movimento)
|
||
// Scrive il movimento e le scadenze, gestendo la rinumerazione se il movimento e' gia presente
|
||
{
|
||
// N.B: _error non viene settato, per non stampare il messaggio di errore 2 volte.
|
||
// basta solo ritornare qualcosa di != da no_error, per evitare le operazioni successive
|
||
// a write_all
|
||
TRectype& head = movimento.curr();
|
||
const long numreg = head.get_long(MOV_NUMREG);
|
||
|
||
if (test_swap())
|
||
{
|
||
const real totdoc = -head.get_real(MOV_TOTDOC);
|
||
head.put(MOV_TOTDOC, totdoc);
|
||
|
||
// Non cambio segno! :-( LL700285
|
||
// const real totdocval = -head.get_real(MOV_TOTDOCVAL);
|
||
// head.put(MOV_TOTDOCVAL, totdocval);
|
||
|
||
const int items = movimento.iva_items();
|
||
for (int i = items - 1 ; i >= 0; i--)
|
||
{
|
||
TRectype & rec_iva = movimento.iva(i);
|
||
|
||
const real imponibile = -rec_iva.get_real(RMI_IMPONIBILE);
|
||
const real imposta = -rec_iva.get_real(RMI_IMPOSTA);
|
||
|
||
rec_iva.put(RMI_IMPONIBILE, imponibile);
|
||
rec_iva.put(RMI_IMPOSTA, imposta);
|
||
}
|
||
}
|
||
|
||
TSaldo_agg saldo;
|
||
int err = NOERR;
|
||
const long old_numreg = doc_contabilized(doc, false);
|
||
if (old_numreg > 0)
|
||
{
|
||
TMovimentoPN oldmov;
|
||
oldmov.curr().put(MOV_NUMREG, old_numreg);
|
||
if (oldmov.read() == NOERR)
|
||
aggiorna_saldi(saldo, oldmov, false); // Leggo i vecchi saldi
|
||
err = movimento.rewrite();
|
||
if (err == NOERR)
|
||
dispatch_transaction(movimento, "MODIFY");
|
||
}
|
||
else
|
||
{
|
||
err = movimento.write();
|
||
if (err == NOERR)
|
||
dispatch_transaction(movimento, "INSERT");
|
||
}
|
||
if (err != NOERR)
|
||
{
|
||
error_box("*** Errore %d scrivendo il movimento contabile %ld.", err, numreg);
|
||
return generic_error;
|
||
}
|
||
// Aggiorno subito i saldi
|
||
aggiorna_saldi(saldo, movimento, true);
|
||
|
||
const bool has_sc = sc_enabled(head.get_date(MOV_DATAREG));
|
||
if (has_sc)
|
||
write_scadenze(doc, numreg == old_numreg); // Recontabilizing?
|
||
|
||
if (good() && in_enabled())
|
||
write_intra(doc);
|
||
|
||
if (good() && (ca_config().get_int("Authorizations") & 0x5)) // No CI qui
|
||
write_anal(doc, movimento);
|
||
|
||
const int tipocoll = _caus->link_m770();
|
||
const bool do_770 = tipocoll == 1 || tipocoll == 5 || tipocoll == 6;
|
||
|
||
if (good() && dongle().active(M77AUT) && do_770)
|
||
write_percip(doc, movimento);
|
||
|
||
// nella 3.1 testava solo l'importo, ma nella 10.0 testava anche has_sc, dal 2/9/2014 si torna al vecchio modo
|
||
if (!doc.get_real(DOC_IMPPAGATO).is_zero())
|
||
{
|
||
if (write_anticipo(doc, movimento) != no_error)
|
||
movimento.remove(); // Se si <20> verificato un errore nella scrittura dell'anticipo rimuove il movimento di prima nota
|
||
}
|
||
|
||
if (good())
|
||
{
|
||
_total_docs++;
|
||
change_doc_status(doc);
|
||
|
||
const TRectype& mov = _movimento->curr();
|
||
TString msg;
|
||
msg.format(FR("--- Movimento contabile $[b,w]%ld$[n,w]"), mov.get_long(MOV_NUMREG));
|
||
msg << TR(" del ") << mov.get(MOV_DATAREG);
|
||
const long protiva = mov.get_long(MOV_PROTIVA);
|
||
if (protiva > 0)
|
||
msg << TR(" protocollo IVA ") << protiva;
|
||
_viswin->add_line(msg);
|
||
|
||
if (_caus->iva() == iva_acquisti && _caus->causale_reg_iva().full())
|
||
{
|
||
if (doc.clifor().get_long(CLI_CODCFASS) > 0)
|
||
{
|
||
TMovimentoPN movreg;
|
||
const error_type err = write_regolarizzazione(doc, movreg);
|
||
if (err == no_error)
|
||
{
|
||
msg.format(FR("--- Movimento regolarizzazione IVA $[b,w]%ld$[n,w] protocollo IVA %ld"),
|
||
movreg.curr().get_long(MOV_NUMREG), movreg.curr().get_long(MOV_PROTIVA));
|
||
_viswin->add_line(msg);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
msg.format(FR("*** Causale con regolarizzazione in assenza di cliente associato al fornitore %ld"), doc.codcf());
|
||
_viswin->add_line(msg);
|
||
}
|
||
}
|
||
|
||
call_exe(doc, movimento);
|
||
}
|
||
|
||
return no_error;
|
||
}
|
||
|
||
error_type TContabilizzazione::write_all_re(TDocumento& doc, TMovimentoPN_VE & movimento)
|
||
// Scrive il movimento e le scadenze, gestendo la rinumerazione se il movimento e' gia presente
|
||
{
|
||
// N.B: _error non viene settato, per non stampare il messaggio di errore 2 volte.
|
||
// basta solo ritornare qualcosa di != da no_error, per evitare le operazioni successive
|
||
// a write_all
|
||
TRectype& head = movimento.curr();
|
||
long numreg = head.get_long(MOV_NUMREG);
|
||
TSaldo_agg saldo;
|
||
|
||
int err = NOERR;
|
||
const long old_numreg = doc_contabilized(doc, false);
|
||
if (old_numreg > 0)
|
||
{
|
||
TMovimentoPN oldmov;
|
||
oldmov.curr().put(MOV_NUMREG, old_numreg);
|
||
if (oldmov.read() == NOERR)
|
||
aggiorna_saldi(saldo, oldmov, false); // Leggo i vecchi saldi
|
||
err = movimento.rewrite();
|
||
}
|
||
else
|
||
err = movimento.write();
|
||
if (err != NOERR)
|
||
{
|
||
error_box("*** Errore %d scrivendo il movimento contabile %ld.", err, numreg);
|
||
return generic_error;
|
||
}
|
||
|
||
// Aggiorno subito i saldi
|
||
aggiorna_saldi(saldo, movimento, true);
|
||
dispatch_transaction(movimento, old_numreg > 0 ? "MODIFY": "INSERT");
|
||
|
||
if (good() && (ca_config().get_int("Authorizations") & 0x5)) // No CIAUT
|
||
write_anal(doc, movimento);
|
||
|
||
if (good())
|
||
{
|
||
_total_docs++;
|
||
change_doc_status(doc);
|
||
|
||
TString msg(TR("--- Movimento contabile "));
|
||
msg << "$[b,w]" << movimento.curr().get_long(MOV_NUMREG) << "$[n,w]";
|
||
msg << " del " << movimento.curr().get(MOV_DATAREG);
|
||
_viswin->add_line(msg);
|
||
}
|
||
|
||
return no_error;
|
||
}
|
||
|
||
error_type TContabilizzazione::compile_head_anticipo(TDocumento& doc, const TMovimentoPN_VE& movimento)
|
||
{
|
||
TString descr;
|
||
|
||
TString8 codcaus = doc.clifor().vendite().get(CFV_CODCAUSINC);
|
||
if (codcaus.blank())
|
||
codcaus = doc.tipo().caus_anticipo();
|
||
const TDate datareg = movimento.curr().get_date(MOV_DATAREG);
|
||
|
||
if (!_caus->read(codcaus,datareg.year()))
|
||
return caus_ant_error;
|
||
|
||
long nr = doc_contabilized(doc, true);
|
||
if (nr <= 0)
|
||
{
|
||
if (get_next_reg_num(nr) != no_error)
|
||
return nr_reg_error;
|
||
}
|
||
|
||
_anticipo = new TMovimentoPN;
|
||
TRectype& head = _anticipo->curr();
|
||
head = movimento.curr(); // Copia tutti i campi...
|
||
head.put(MOV_NUMREG,nr);
|
||
head.zero(MOV_DATA74TER);
|
||
head.put(MOV_TIPODOC,_caus->tipo_doc());
|
||
head.put(MOV_CODCAUS,_caus->codice());
|
||
descr = doc.get_bool(DOC_ACCSALDO) ? TR("Saldo fattura") : TR("Acconto fattura");
|
||
descr << TR(" n. ") << doc.numero();
|
||
descr << TR(" del ") << doc.get_date(DOC_DATADOC).string();
|
||
head.put(MOV_DESCR,descr);
|
||
head.put(MOV_TIPOMOV,char(_caus->tipomov()+'0'));
|
||
head.zero(MOV_TIPO);
|
||
head.zero(MOV_CODCF);
|
||
head.zero(MOV_REG);
|
||
head.zero(MOV_PROTIVA);
|
||
head.zero(MOV_CODPAG);
|
||
head.zero(MOV_CORRLIRE);
|
||
head.zero(MOV_CORRVALUTA);
|
||
head.zero(MOV_CODVALI);
|
||
head.zero(MOV_CAMBIOI);
|
||
head.zero(MOV_INVIATO);
|
||
head.zero(MOV_INVIVA);
|
||
head.zero(MOV_LIQDIFF);
|
||
head.zero(MOV_IVAXCASSA);
|
||
if (sc_enabled(datareg))
|
||
{
|
||
TCurrency_documento p(doc.get_real(DOC_IMPPAGATO), doc);
|
||
TCurrency_documento plit(p); p.change_to_firm_val();
|
||
if (doc.in_valuta())
|
||
{
|
||
head.put(MOV_TOTDOC, plit.get_num());
|
||
head.put(MOV_TOTDOCVAL, p.get_num());
|
||
}
|
||
else
|
||
{
|
||
head.put(MOV_TOTDOC, p.get_num());
|
||
head.zero(MOV_TOTDOCVAL);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
head.zero(MOV_TOTDOC);
|
||
head.zero(MOV_TOTDOCVAL);
|
||
}
|
||
|
||
// Memorizza il movimento contabile di destinazione!
|
||
doc.put(DOC_NUMANT, nr);
|
||
// Scrive sulla testata dell'anticipo il numero di documento originale
|
||
head.put(MOV_DPROVV, doc.get(DOC_PROVV));
|
||
head.put(MOV_DANNO, doc.get(DOC_ANNO));
|
||
head.put(MOV_DCODNUM, doc.get(DOC_CODNUM));
|
||
head.put(MOV_DNDOC, doc.get(DOC_NDOC));
|
||
head.put(MOV_CONTSEP, doc.get(DOC_CONTSEP));
|
||
|
||
return no_error;
|
||
}
|
||
|
||
char TContabilizzazione::sezione() const
|
||
{
|
||
char sezione = ' ';
|
||
const char tipoc = _co_cliente.tipo();
|
||
|
||
tipo_movimento tm = (tipo_movimento)_caus->tipomov();
|
||
sezione = _caus->sezione(1); // Usa la sezione della causale
|
||
|
||
if (sezione <= ' ') // Se non c'e' la sezione bell'e' ch'e' pronta
|
||
{
|
||
if (tm == tm_fattura || tm == tm_insoluto) // calcola in base al tipo movimento e
|
||
sezione = (tipoc == 'C') ? 'D' : 'A'; // al tipo cliente/fornitore
|
||
else
|
||
sezione = (tipoc == 'C') ? 'A' : 'D';
|
||
}
|
||
return sezione;
|
||
}
|
||
|
||
error_type TContabilizzazione::search_clifo_bill(const TString& catven)
|
||
|
||
{
|
||
_error = no_error;
|
||
const TRectype& clifo = _clifo->curr();
|
||
const long codcf = clifo.get_long(CLI_CODCF);
|
||
const char tipocf = clifo.get_char(CLI_TIPOCF);
|
||
_co_cliente.set(0,0,0);
|
||
|
||
// Reperisce il conto del cliente nel seguente ordine, appena ne trova uno valido:
|
||
// - Categoria vendita
|
||
// - file clienti
|
||
// - causale
|
||
|
||
_cve->put("CODTAB", catven);
|
||
if (_cve->read() == NOERR)
|
||
_co_cliente.set(_cve->get_int("I1"), _cve->get_int("I2"),codcf,tipocf);
|
||
if (!_co_cliente.ok())
|
||
{
|
||
_co_cliente.set(clifo.get_int(CLI_GRUPPO),clifo.get_int(CLI_CONTO),codcf,tipocf);
|
||
if (!_co_cliente.ok()) // se non e' valido, reperiscilo dalla riga #1 della causale
|
||
{
|
||
_caus->bill(1,_co_cliente); // conto della riga 1
|
||
if (_co_cliente.tipo() != ' ')
|
||
_co_cliente.codclifo() = codcf;
|
||
if (!_co_cliente.ok())
|
||
_error = clifo_error;
|
||
}
|
||
}
|
||
return _error;
|
||
}
|
||
|
||
error_type TContabilizzazione::search_counter_bill(TDocumento& doc, const TDate& datareg)
|
||
{
|
||
_error = no_error;
|
||
// cerca il conto relativo alla riga di causale:
|
||
// 1 Rimessa diretta o contanti (banca) riga 2
|
||
// 2 Tratta riga 3
|
||
// 3 Ricevuta bancaria riga 4
|
||
// 4 Cessione riga 5
|
||
// 5 Paghero' riga 6
|
||
// 6 Lettera di credito riga 7
|
||
// 7 Tratta accettata riga 8
|
||
// 8 Rapporti interban. diretti riga 2
|
||
// 9 Bonifici riga 2
|
||
// Se il saldaconto e' attivo prende il conto relativo al tipo pagamento
|
||
// Altrimenti sempre la riga 2
|
||
|
||
if (sc_enabled(datareg))
|
||
{
|
||
int tipopag = doc.pagamento().tipo_rata(0); // Quello della prima rata... prolly is right .. ;P
|
||
_caus->bill(tipopag>0 && tipopag<8 ? tipopag+1:2,_co_controp);
|
||
if (!_co_controp.ok())
|
||
_caus->bill(2,_co_controp);
|
||
}
|
||
else
|
||
_caus->bill(2,_co_controp);
|
||
if (!_co_controp.ok())
|
||
_error = counter_p_ant_error;
|
||
return _error;
|
||
}
|
||
|
||
error_type TContabilizzazione::compile_rows_anticipo(TDocumento& doc)
|
||
{
|
||
// Per compilare le righe ci si ispira alla contabilizzazione effetti
|
||
// per reperire il conto clienti si guarda prima sul record cliente
|
||
// e poi al limite la riga della causale
|
||
// per il conto di contropartita se non c'e' il saldaconto lo si prende dalla
|
||
// seconda riga. Se il saldaconto esiste si consulta la riga relativa al
|
||
// tipo di pagamento.
|
||
const TString4 codpag(doc.get(DOC_CODPAG));
|
||
const TString4 catven(doc.get(DOC_CATVEN));
|
||
const TRectype& mov = _anticipo->curr();
|
||
const TDate datareg = mov.get_date(MOV_DATAREG);
|
||
if (search_clifo_bill(catven) == no_error && search_counter_bill(doc, datareg) == no_error)
|
||
{
|
||
TCurrency_documento importo(doc.get_real(DOC_IMPPAGATO), doc); importo.change_to_firm_val();
|
||
const TString4 codes = mov.get(MOV_ANNOES);
|
||
const long numreg = mov.get_long(MOV_NUMREG);
|
||
TRectype& c_rec = _anticipo->cg(0);
|
||
// setta i valori per la riga cliente
|
||
c_rec.put(RMV_ANNOES,codes);
|
||
c_rec.put(RMV_DATAREG,datareg);
|
||
c_rec.put(RMV_NUMREG,numreg);
|
||
c_rec.put(RMV_NUMRIG,1);
|
||
c_rec.put(RMV_SEZIONE,_caus->sezione_clifo());
|
||
c_rec.put(RMV_TIPOC,_co_cliente.tipo());
|
||
c_rec.put(RMV_GRUPPO,_co_cliente.gruppo());
|
||
c_rec.put(RMV_CONTO,_co_cliente.conto());
|
||
c_rec.put(RMV_SOTTOCONTO,_co_cliente.sottoconto());
|
||
c_rec.put(RMV_GRUPPOC,_co_controp.gruppo());
|
||
c_rec.put(RMV_CONTOC,_co_controp.conto());
|
||
c_rec.put(RMV_SOTTOCONTOC,_co_controp.sottoconto());
|
||
c_rec.put(RMV_ROWTYPE,sc_enabled(datareg) ? "K" : " ");
|
||
c_rec.put(RMV_IMPORTO, importo.get_num());
|
||
|
||
TRectype& co_rec = _anticipo->cg(1);
|
||
// setta i valori per la riga contropartita
|
||
co_rec = c_rec; // Swappa i conti ed il numero di riga
|
||
co_rec.put(RMV_NUMRIG,2);
|
||
co_rec.put(RMV_TIPOC,"");
|
||
co_rec.put(RMV_SEZIONE,_caus->sezione_clifo() == 'A' ? 'D' : 'A');
|
||
co_rec.put(RMV_GRUPPO,_co_controp.gruppo());
|
||
co_rec.put(RMV_CONTO,_co_controp.conto());
|
||
co_rec.put(RMV_SOTTOCONTO,_co_controp.sottoconto());
|
||
co_rec.put(RMV_TIPOCC,_co_cliente.tipo());
|
||
co_rec.put(RMV_GRUPPOC,_co_cliente.gruppo());
|
||
co_rec.put(RMV_CONTOC,_co_cliente.conto());
|
||
co_rec.put(RMV_SOTTOCONTOC,_co_cliente.sottoconto());
|
||
co_rec.put(RMV_ROWTYPE,sc_enabled(datareg) ? "I" : " ");
|
||
}
|
||
return _error;
|
||
}
|
||
|
||
error_type TContabilizzazione::write_pagamento_anticipo(TDocumento& doc)
|
||
{
|
||
const TRectype& mov = _anticipo->curr();
|
||
const int anno = mov.get_date(MOV_DATAREG).year();
|
||
const long numreg = mov.get_long(MOV_NUMREG);
|
||
const TString8 numpart = mov.get(MOV_NUMDOC); // Nessun controllo se prot.iva o numdoc xche' tanto proviene dal mov precedentemente scritto
|
||
|
||
TPartita* partita = new TPartita(_co_cliente,anno,numpart);
|
||
partita->allinea();
|
||
|
||
// reperire il numero della riga partita (nrigp) appena aggiunta
|
||
int nriga = (int) TPartita::UNASSIGNED;
|
||
// Cerca la riga di partita con riferimento alla fattura che si sta pagando
|
||
for (int r = partita->last(); r > 0; r = partita->pred(r))
|
||
{
|
||
TRiga_partite& rpart = partita->riga(r);
|
||
if (rpart.is_fattura())
|
||
{
|
||
TString8 s1 = rpart.get(PART_NUMDOC); s1.trim();
|
||
TString8 s2 = numpart; s2.trim();
|
||
if (s1 == s2) // Bisogna tener conto dell'allineamento!
|
||
{
|
||
nriga = r;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (nriga == TPartita::UNASSIGNED)
|
||
{
|
||
delete partita;
|
||
return write_part_error;
|
||
}
|
||
|
||
int nrigp = partita->primo_pagamento(numreg);
|
||
if (nrigp > 0)
|
||
{
|
||
const TRiga_partite& rfatt = partita->riga(nriga);
|
||
for (int r = rfatt.rate(); r > 0; r--)
|
||
partita->elimina_pagamento(nriga, r, nrigp);
|
||
partita->elimina_pagamento(TPartita::UNASSIGNED, TPartita::UNASSIGNED, nrigp);
|
||
if (partita->esiste(nrigp)) // Non dovrebbe succedere mai
|
||
nrigp = 0;
|
||
}
|
||
|
||
// Cerco di riutilizzare lo stesso nrigp della eventuale contabilizzazione precedente
|
||
TRiga_partite& riga_part = partita->new_row(nrigp);
|
||
nrigp = riga_part.get_int(PART_NRIGA);
|
||
|
||
// Compila la riga di partita per il pagamento
|
||
riga_part.put(PART_TIPOMOV,_caus->tipomov());
|
||
riga_part.put(PART_TIPOPAG, 1 ); // Pagamento in contanti-> tipo 1
|
||
riga_part.put(PART_NREG, numreg);
|
||
riga_part.put(PART_NUMRIG,1); // Riferimento alla riga 1 del movimento
|
||
riga_part.put(PART_DATAREG, mov.get_date(MOV_DATAREG));
|
||
riga_part.put(PART_DATADOC, mov.get_date(MOV_DATADOC));
|
||
riga_part.put(PART_DATAPAG, mov.get_date(MOV_DATADOC));
|
||
riga_part.put(PART_NUMDOC, numpart); // E' lo stesso riferimento
|
||
riga_part.put(PART_SEZ, sezione());
|
||
riga_part.put(PART_CODCAUS, _caus->codice());
|
||
|
||
TCurrency_documento impval(doc.get_real(DOC_IMPPAGATO), doc);
|
||
TCurrency_documento imp(impval); imp.change_to_firm_val();
|
||
const real cambio = doc.get_real(DOC_CAMBIO);
|
||
const TString4 val(doc.get(DOC_CODVAL));
|
||
const TDate datacam(doc.get_date(DOC_DATACAMBIO));
|
||
const bool valuta = val.not_empty();
|
||
riga_part.put(PART_IMPORTO,imp.get_num());
|
||
riga_part.put(PART_IMPORTOVAL,impval.get_num());
|
||
riga_part.put(PART_IMPTOTDOC,imp.get_num());
|
||
riga_part.put(PART_IMPTOTVAL,impval.get_num());
|
||
riga_part.put(PART_CODVAL,val);
|
||
riga_part.put(PART_CAMBIO,cambio);
|
||
riga_part.put(PART_DATACAM,doc.get_date(DOC_DATACAMBIO));
|
||
riga_part.put(PART_TIPOCF,_co_cliente.tipo());
|
||
riga_part.put(PART_SOTTOCONTO,_co_cliente.sottoconto());
|
||
riga_part.put(PART_DESCR, mov.get(MOV_DESCR));
|
||
|
||
// Compila la riga di pagamento:
|
||
|
||
// Scorre le scadenze di questa fattura, e ne completa il pagamento partendo
|
||
// dalla rata piu' vecchia.
|
||
TRiga_partite& rpp = partita->riga(nriga);
|
||
real abb;
|
||
real ipp = (real) (valuta ? impval.get_num() : imp.get_num());
|
||
TValuta tval(val, datacam, cambio);
|
||
char old_ap, new_ap;
|
||
TImporto old_abb, old_diffcam, new_abb, new_diffcam;
|
||
const int nrate = rpp.rate();
|
||
const bool is_saldo_doc = doc.get_bool(DOC_ACCSALDO);
|
||
char s_a = 'A';
|
||
for (int i=1; i<=nrate; i++)
|
||
{
|
||
TRiga_scadenze& rs = rpp.rata(i);
|
||
real res = rs.residuo(valuta).valore(); // Sul residuo da pagare per questa rata
|
||
TRectype& riga_pagamento = partita->pagamento(nriga,i,nrigp); // Nuova riga di pagamento
|
||
// Compila la riga... e scala l'importo residuo partendo dalla piu' vecchia
|
||
// setta i flags di saldato/acconto
|
||
// ANNO, NUMPART, NRIGA, NRATA, NRIGP dovrebbero essere gia' compilati
|
||
riga_pagamento.put(PAGSCA_TIPOC,_co_cliente.tipo());
|
||
riga_pagamento.put(PAGSCA_SOTTOCONTO,_co_cliente.sottoconto());
|
||
s_a = 'S';
|
||
if (ipp <= ZERO)
|
||
ipp = ZERO;
|
||
if (res > ipp || i == nrate) // sull'ultima rata mette tutto il resto...
|
||
{
|
||
res = ipp;
|
||
imp.set_num(ZERO);
|
||
if (!is_saldo_doc)
|
||
s_a = 'A';
|
||
}
|
||
else
|
||
ipp -= res;
|
||
riga_pagamento.put(PAGSCA_ACCSAL, s_a);
|
||
riga_pagamento.put(valuta ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO, res);
|
||
|
||
if (valuta)
|
||
{
|
||
TCurrency_documento impval(res);
|
||
impval.change_to_firm_val();
|
||
riga_pagamento.put(PAGSCA_IMPORTO, impval.get_num());
|
||
}
|
||
riga_pagamento.put(PAGSCA_TIPOCC,_co_controp.tipo());
|
||
riga_pagamento.put(PAGSCA_GRUPPOC,_co_controp.gruppo());
|
||
riga_pagamento.put(PAGSCA_CONTOC,_co_controp.conto());
|
||
riga_pagamento.put(PAGSCA_SOTTOCONTC,_co_controp.sottoconto());
|
||
|
||
TRectype rp(riga_pagamento);
|
||
if (is_saldo_doc)
|
||
rp.put(PAGSCA_ACCSAL, 'S');
|
||
|
||
partita->modifica_pagamento(rp, tval, old_ap, old_abb, old_diffcam, new_ap, new_abb, new_diffcam, true);
|
||
abb += new_abb.valore();
|
||
}
|
||
|
||
// Vediamo se vi sono abbuoni, in questo caso si completa il movimento
|
||
// contabile di anticipo, con la riga appropriata, di abbuoni attivi/passivi cambiamo pure la riga relativa
|
||
// all'importo cliente, ovvero lo settiamo al valore totale della fattura... ;)
|
||
// Dentro new_ap avremo se l'abbuono e' attivo o passivo, in new_abb avremo l'importo
|
||
TBill abb_bill;
|
||
if (abb != ZERO)
|
||
{
|
||
// Reperisce il conto di contropartita per gli abbuoni dalla causale: 9 passivi 10 attivi
|
||
const int nrigc = new_ap == 'A' ? RIGA_ABBUONI_ATTIVI : RIGA_ABBUONI_PASSIVI;
|
||
_caus->bill(nrigc, abb_bill);
|
||
if (abb_bill.ok())
|
||
{
|
||
TRectype& first_row = _anticipo->cg(0); // Riga cli/fo
|
||
first_row.put(RMV_IMPORTO, rpp.get_real(PART_IMPTOTDOC)); // Aggiusta l'importo totale
|
||
TRectype& abb_row = _anticipo->cg(2); // Riga abbuoni ...
|
||
abb_row = first_row;
|
||
abb_row.put(RMV_NUMRIG,3);
|
||
abb_row.put(RMV_TIPOC,"");
|
||
|
||
char ab_sez = 'D';
|
||
const char cf_sez = _caus->sezione_clifo();
|
||
if (cf_sez == 'D' && new_ap == 'P' ||
|
||
cf_sez == 'A' && new_ap == 'A')
|
||
ab_sez = 'A';
|
||
abb_row.put(RMV_SEZIONE, ab_sez);
|
||
abb_row.put(RMV_GRUPPO,abb_bill.gruppo());
|
||
abb_row.put(RMV_CONTO,abb_bill.conto());
|
||
abb_row.put(RMV_SOTTOCONTO,abb_bill.sottoconto());
|
||
abb_row.put(RMV_TIPOCC,_co_cliente.tipo());
|
||
abb_row.put(RMV_GRUPPOC,_co_cliente.gruppo());
|
||
abb_row.put(RMV_CONTOC,_co_cliente.conto());
|
||
abb_row.put(RMV_SOTTOCONTOC,_co_cliente.sottoconto());
|
||
abb_row.put(RMV_IMPORTO, abs(abb));
|
||
abb_row.put(RMV_ROWTYPE, new_ap);
|
||
}
|
||
else
|
||
_error = cau_abb_error;
|
||
}
|
||
|
||
// Infine scrive sta partita...
|
||
if (good() && !partita->write())
|
||
//error_box("Si e' verificato un errore scrivendo il pagamento del movimento di anticipo");
|
||
_error = write_part_error;
|
||
delete partita;
|
||
return _error;
|
||
}
|
||
|
||
error_type TContabilizzazione::write_anticipo(TDocumento& doc, const TMovimentoPN_VE& movimento)
|
||
{
|
||
// Questo movimento viene scritto solo se e' stato versato un anticipo di pagamento
|
||
// Crea 1 testata, 1 riga contabile e la relativa riga di pagamento sulla partita a cui fa riferimento
|
||
// La testata e' praticamente la stessa del movimento appena scritto, tranne che per il numero di
|
||
// protocollo, il numero di registrazione la descrizione, i totali in lire/valuta,
|
||
// la condizione pagamento...
|
||
const TRectype& dbghead = movimento.curr();
|
||
|
||
_error = compile_head_anticipo(doc, movimento);
|
||
if (_error == no_error && _anticipo != NULL)
|
||
{
|
||
// Una volta compilata la testa... compila le righe...
|
||
if (_anticipo)
|
||
{
|
||
_error = compile_rows_anticipo(doc);
|
||
if (_error == no_error)
|
||
{
|
||
// Scrive il movimento... gestendo la rinumerazione
|
||
if (sc_enabled(_anticipo->curr().get_date(MOV_DATAREG)))
|
||
// ... il pagamento vero e proprio, scrivendo la partita e modificando
|
||
// il movimento se vi sono abbuoni
|
||
write_pagamento_anticipo(doc);
|
||
|
||
TSaldo_agg saldo;
|
||
|
||
int err = NOERR;
|
||
const long numant = doc_contabilized(doc, true);
|
||
if (numant > 0)
|
||
{
|
||
TMovimentoPN oldant;
|
||
oldant.curr().put(MOV_NUMREG, numant);
|
||
if (oldant.read() == NOERR)
|
||
aggiorna_saldi(saldo, oldant, false);
|
||
err = _anticipo->rewrite();
|
||
if (err == NOERR)
|
||
dispatch_transaction(*_anticipo, "MODIFY");
|
||
}
|
||
else
|
||
{
|
||
err = _anticipo->write();
|
||
if (err == NOERR)
|
||
dispatch_transaction(*_anticipo, "INSERT");
|
||
}
|
||
if (err != NOERR)
|
||
{
|
||
error_box("Errore %d scrivendo il movimento di anticipo pagamento %ld.",
|
||
err, _anticipo->curr().get_long(MOV_NUMREG));
|
||
return generic_error;
|
||
}
|
||
else
|
||
{
|
||
TString msg(TR("--- Movimento di anticipo "));
|
||
msg << "$[b,w]" << _anticipo->curr().get(MOV_NUMREG) << "$[n,w]";
|
||
msg << TR(" del ") << _anticipo->curr().get(MOV_DATAREG);
|
||
_viswin->add_line(msg);
|
||
}
|
||
aggiorna_saldi(saldo, *_anticipo, true);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (_anticipo)
|
||
{
|
||
delete _anticipo;
|
||
_anticipo = NULL;
|
||
}
|
||
|
||
return _error;
|
||
}
|
||
|
||
error_type TContabilizzazione::write_intra(TDocumento& doc)
|
||
{
|
||
const TRectype& rm = _movimento->curr();
|
||
|
||
const TDate data_reg = rm.get(MOV_DATAREG);
|
||
/* Ora so fare le rettifiche! 29-09-2015
|
||
// Controllo la liceita' della scrittura del movimento intra
|
||
const TDate data_intra = rm.get(MOV_DATACOMPI);
|
||
if (data_intra.ok() && data_intra < data_reg)
|
||
{
|
||
TIntra_frequency freq;
|
||
const char tipo_intra = _caus->iva() == iva_acquisti ? 'A' : 'C';
|
||
if (freq.compare_periodo(data_intra, data_reg, tipo_intra) < 0)
|
||
{
|
||
_error = intra_rett_error;
|
||
display_error(doc);
|
||
_error = no_error;
|
||
return _error; // Non posso fare movimenti, ma devo fare rettifiche
|
||
}
|
||
}
|
||
*/
|
||
|
||
// Scrive il movimento INTRA raggruppando per NATURA+NOMENCLATURA+CONSEGNA+TRASPORTO+PAESE+PAESEORIG+PROV
|
||
// Siccome NATURA, CONSEGNA, TRASPORTO e PAESE sono relativi alla testata del documento,
|
||
// il raggruppamento effettivo viene fatto solo per NOMENCLATURA+PAESEORIG+PROV
|
||
// NB: per i profani (come me :P) NOMENCLATURA COMBINATA e CLASSE DOGANALE sono la medesima cosa.
|
||
|
||
TLocalisamfile& intra = *_intra;
|
||
|
||
// Un po' di cache...
|
||
TDB_cache& cchh = cache();
|
||
TRecord_array rintra(LF_RINTRA, "NUMRIG");
|
||
TAssoc_array righe;
|
||
|
||
const TString4 codvali(rm.get(MOV_CODVALI));
|
||
const real cambioi = rm.get(MOV_CAMBIOI);
|
||
const TRectype& por_rec = cchh.get("%POR", doc.get(DOC_CODPORTO));
|
||
const TString16 consegna(por_rec.get("S3")); // condizioni di consegna
|
||
const int trasporto = por_rec.get_int("I0"); // tipo di trasporto...
|
||
const char natura = doc.tipo().get("S3")[3]; // natura della transazione, valida per tutte le righe del documento
|
||
const long numreg = rm.get_long(MOV_NUMREG);
|
||
real totale_righe, massanun, unsuppun;
|
||
const real cambio = doc.cambio();
|
||
const bool is_val = doc.in_valuta();
|
||
const bool is_cessione = rm.get_char(MOV_TIPO)=='C';
|
||
const bool nota_credito = doc.tipo().nota_credito();
|
||
const TString4 paese = _clifo->curr().get(CLI_STATOPAIV); // Paese del cliente/fornitore...
|
||
|
||
// Scorre le righe documento (prendendo solamente quelle relative agli articoli veri e propri)
|
||
// Effettuando il raggruppamento in un comodo TAssoc_array
|
||
TToken_string key;
|
||
int numrig = 1;
|
||
FOR_EACH_PHYSICAL_RDOC(doc, i, prdoc) if (prdoc->is_articolo())
|
||
{
|
||
const TRiga_documento& rr = doc[i];
|
||
const TRectype& rec_anamag = cchh.get(LF_ANAMAG, rr.get(RDOC_CODARTMAG));
|
||
const TString16 nomenclatura = rec_anamag.get(ANAMAG_CLASSDOG);
|
||
|
||
const TRectype& rec_noc = cchh.get("%NOC", nomenclatura);
|
||
const char noc_s4 = rec_noc.get_char("S4"); // Obbligatoriet<65> unit<69> di misura supplementare
|
||
bool ums_obbl = noc_s4 > ' ';
|
||
if (ums_obbl && noc_s4 != 'E')
|
||
ums_obbl = is_cessione ? noc_s4=='C' : noc_s4=='A';
|
||
|
||
const TString4 ums = rec_noc.get("S5");
|
||
const real massanun = rec_anamag.get_real(ANAMAG_MASSANUN); // Massa KG
|
||
const real unsuppun = rec_anamag.get_real(ANAMAG_UNSUPPUN); // Massa UMS
|
||
const TString16 paeseorig = is_cessione ? EMPTY_STRING : rec_anamag.get(ANAMAG_PAESE); // Campo solo per Acquisti
|
||
TString4 provincia;
|
||
if (is_cessione)
|
||
provincia = rec_anamag.get(ANAMAG_PROV);
|
||
else
|
||
{
|
||
const TString8 codmag = rr.get(RDOC_CODMAG);
|
||
TString4 com = cchh.get("MAG", codmag, "S5"); // Comune del magazzino
|
||
if (com.empty())
|
||
{
|
||
const long codditta = prefix().get_codditta();
|
||
TString8 codulc; codulc.format("%ld|1", codditta);
|
||
const TRectype& unloc = cchh.get(LF_UNLOC, codulc);
|
||
com = unloc.get(ULC_COMULC);
|
||
}
|
||
key.format(" |%s", (const char*)com);
|
||
provincia = cchh.get(LF_COMUNI, key, COM_PROVCOM);
|
||
}
|
||
|
||
if (nomenclatura.blank() || (ums_obbl && unsuppun.is_zero() && ums.blank()) || massanun.is_zero() || provincia.blank())
|
||
{
|
||
TString msg;
|
||
msg << "--- L'articolo " << rec_anamag.get(ANAMAG_CODART) << " non riporta tutti i dati necessari per il movimento intracomunitario.";
|
||
_viswin->add_line(msg);
|
||
msg = " Si consiglia di verificare i seguenti valori sull'anagrafica:";
|
||
_viswin->add_line(msg);
|
||
msg = " ";
|
||
if (nomenclatura.blank()) msg << "nomenclatura combinata; ";
|
||
if (ums_obbl && unsuppun.is_zero()) msg << "unit<EFBFBD> di misura supplementare; ";
|
||
if (massanun.is_zero()) msg << "massa netta unitaria; ";
|
||
if (provincia.blank()) msg << (is_cessione ? "provincia d'origine; " : "provincia di destinazione; ");
|
||
msg.rtrim(2); msg << '.'; // Sostituisce l'ultimo punto e virgola con un punto
|
||
_viswin->add_line(msg);
|
||
}
|
||
|
||
key.cut(0);
|
||
key.add(nomenclatura);
|
||
key.add(paeseorig);
|
||
key.add(provincia);
|
||
TRectype* rc = (TRectype*)righe.objptr(key); // Riga intra
|
||
if (rc == NULL)
|
||
{
|
||
rc = new TRectype(LF_RINTRA);
|
||
rc->put("NUMREG", numreg);
|
||
rc->put("NUMRIG", numrig++);
|
||
rc->put("NATURA", natura);
|
||
rc->put("CONSEGNA", consegna);
|
||
rc->put("TRASPORTO", trasporto);
|
||
|
||
rc->put("NOMENCL", nomenclatura);
|
||
rc->put("UMS", ums);
|
||
rc->put("PAESE", paese);
|
||
rc->put("PAESEORIG", paeseorig);
|
||
rc->put("PROV", provincia);
|
||
righe.add(key, rc);
|
||
}
|
||
const real qta = rr.get_real(RDOC_QTA);
|
||
TCurrency_documento imp_val(rr.TVariable_rectype::exist("VALINTRA") ? rr.get_real("VALINTRA") : rr.importo(true, false), doc);
|
||
TCurrency_documento imp(imp_val); imp.change_to_firm_val();
|
||
imp_val.change_value(codvali, cambioi);
|
||
real ammeuro = rc->get_real("AMMLIRE");
|
||
real ammvaluta = rc->get_real("AMMVALUTA");
|
||
real massakg = rc->get_real("MASSAKG");
|
||
real massaums = rc->get_real("MASSAUMS");
|
||
real valstat = rc->get_real("VALSTAT");
|
||
|
||
if (nota_credito)
|
||
{
|
||
ammeuro -= imp.get_num();
|
||
ammvaluta -= is_val ? imp_val.get_num() : ZERO;
|
||
}
|
||
else
|
||
{
|
||
ammeuro += imp.get_num();
|
||
ammvaluta += is_val ? imp_val.get_num() : ZERO;
|
||
}
|
||
|
||
real peso = qta * massanun; // peso netto
|
||
if (peso.is_zero())
|
||
peso = rr.get_real(RDOC_PNETTO);
|
||
massakg += peso;
|
||
|
||
if (ums_obbl || ums.full() || !unsuppun.is_zero())
|
||
{
|
||
real qta_ums;
|
||
// Campo Fisico o Formulato? TAuto_variable_rectype::exist("MASSAUMS") <20> sempre TRUE!
|
||
if (rr.TVariable_rectype::exist("MASSAUMS"))
|
||
qta_ums = rr.get_real("MASSAUMS");
|
||
else
|
||
{
|
||
// Cerco di convertire l'unit<69> di misura su rdoc nella unit<69> di misura supplementare
|
||
const TString4 um = rr.get(RDOC_UMQTA);
|
||
if (ums.full() && um.full())
|
||
{
|
||
if (ums == um) // Se coincidono, ho gi<67> finito ...
|
||
qta_ums = qta;
|
||
else
|
||
{
|
||
TArticolo& art = rr.articolo();
|
||
qta_ums = art.convert_to_um(qta, ums, um); // ... altrimenti converto
|
||
}
|
||
}
|
||
}
|
||
if (qta_ums.is_zero()) // Se non sono riuscito in altro modo ...
|
||
qta_ums = qta * unsuppun; // ... calcolo peso/qta in unit<69> di misura supplementare
|
||
|
||
massaums += qta_ums;
|
||
}
|
||
|
||
real vs; // Valore statistico
|
||
// Campo Fisico o Formulato? TAuto_variable_rectype::exist("VALSTAT") <20> sempre TRUE!
|
||
if (rr.TVariable_rectype::exist("VALSTAT"))
|
||
{
|
||
TCurrency_documento vstat(rr.get_real("VALSTAT"), doc);
|
||
vstat.change_to_firm_val();
|
||
vs = vstat.get_num();
|
||
}
|
||
else
|
||
{
|
||
vs = qta * rec_anamag.get_real(ANAMAG_VALSTATUN);
|
||
if (vs.is_zero())
|
||
vs = imp.get_num();
|
||
}
|
||
if (nota_credito)
|
||
valstat -= vs;
|
||
else
|
||
valstat += vs;
|
||
|
||
rc->put("AMMLIRE", ammeuro);
|
||
rc->put("AMMVALUTA", ammvaluta);
|
||
rc->put("MASSAKG", massakg);
|
||
rc->put("MASSAUMS", massaums);
|
||
rc->put("VALSTAT", valstat);
|
||
|
||
// Il totale delle righe in Euro!
|
||
if (nota_credito)
|
||
totale_righe -= imp.get_num();
|
||
else
|
||
totale_righe += imp.get_num();
|
||
}
|
||
|
||
if (_error == no_error)
|
||
{
|
||
// Copia il contenuto dell'assoc nel record array
|
||
TRectype* rc = new TRectype(LF_RINTRA);
|
||
rc->put("NUMREG", numreg);
|
||
rintra.set_key(rc);
|
||
for(rc = (TRectype*)righe.first_item(); rc != NULL; rc = (TRectype*)righe.succ_item())
|
||
rintra.add_row(*rc); // Devo aggiungere una copia della riga dell'assoc array!
|
||
// Testa (de coccio...)
|
||
intra.zero();
|
||
intra.put("NUMREG", numreg);
|
||
intra.put("DATAREG", rm.get_date(MOV_DATAREG));
|
||
intra.put("TIPOMOV", is_cessione ? 'C' : 'A'); // 'C' cessione 'A' acquisto
|
||
intra.put("TIPOCF", rm.get(MOV_TIPO));
|
||
intra.put("CODCF", rm.get_long(MOV_CODCF));
|
||
intra.put("TOTDOC", totale_righe);
|
||
intra.put("TOTDOCIMM", totale_righe);
|
||
if (_caus->valintra() && ::is_euro_value(codvali))
|
||
{
|
||
TString4 codval = TCurrency::get_firm_val();
|
||
if (codval.empty())
|
||
codval = TCurrency::get_euro_val();
|
||
intra.put("CODVAL", codval);
|
||
}
|
||
else
|
||
intra.put("CODVAL", codvali);
|
||
intra.put("CAMBIO", cambioi);
|
||
|
||
intra.write_rewrite(); // rewrite succede con le ricontabilizzazioni
|
||
if (intra.status() == NOERR)
|
||
{
|
||
// righe!
|
||
if (rintra.write(true) != NOERR) // Forza la riscrittura se necessario
|
||
_error = intra_mov_error;
|
||
}
|
||
else
|
||
_error = intra_mov_error;
|
||
}
|
||
|
||
return _error;
|
||
}
|
||
|
||
error_type TContabilizzazione::write_anal(TDocumento& doc, const TMovimentoPN& movimento)
|
||
{
|
||
// Controlla flag sulla causale
|
||
if (!_caus->link_analitica())
|
||
return _error;
|
||
|
||
TConfig& cfg = ca_config();
|
||
const TDate data_att = cfg.get("DtAttCa");
|
||
if (data_att.ok())
|
||
{
|
||
const TDate data_cmp = movimento.curr().get(MOV_DATACOMP);
|
||
if (data_cmp < data_att) // La data di competenza precede la data di attivazione analitica
|
||
return _error;
|
||
}
|
||
|
||
bool has_anal_bill = false;
|
||
for (int i = movimento.cg_items(); i > 0; i--)
|
||
{
|
||
const TRectype& cgrow = movimento.cg_rows().row(i);
|
||
const TBill bill(cgrow);
|
||
if (bill.is_analitico())
|
||
{
|
||
has_anal_bill = true;
|
||
break;
|
||
}
|
||
}
|
||
if (has_anal_bill)
|
||
{
|
||
TContabilizzazione_analitica canal(*this);
|
||
const long numreg_cg = movimento.curr().get_long(MOV_NUMREG);
|
||
TAnal_mov mov;
|
||
canal.elabora(doc, numreg_cg, _viswin, _can_write, mov);
|
||
}
|
||
|
||
return _error;
|
||
}
|
||
|
||
TRecnotype TContabilizzazione::kill_righe_percip(TIsam_handle logic, char tipopercip, long codpercip, long nprog) const
|
||
{
|
||
CHECKD(logic == LF_RVER || logic == LF_RPAG, "Invalid file number ", logic);
|
||
CHECKD(nprog > 0, "Invalid NPROGR ", nprog);
|
||
TRelation rel(logic);
|
||
TRectype& riga = rel.curr();
|
||
riga.put(VER_CODDITTA, prefix().firm().codice());
|
||
riga.put(VER_TIPOA, tipopercip);
|
||
riga.put(VER_CODANAGR, codpercip);
|
||
riga.put(VER_NPROG, nprog);
|
||
TCursor cur(&rel, "", 1, &riga, &riga);
|
||
const TRecnotype tot = cur.items();
|
||
if (tot > 0)
|
||
{
|
||
cur.freeze();
|
||
for (cur = 0L; cur.pos() < tot; ++cur)
|
||
cur.file().remove();
|
||
}
|
||
return tot;
|
||
}
|
||
|
||
|
||
error_type TContabilizzazione::write_percip(TDocumento& doc, const TMovimentoPN& movimento)
|
||
{
|
||
const char tipopercip = doc.clifor().get_char(CLI_TIPOAPER);
|
||
const long codpercip = doc.clifor().get_long(CLI_CODANAGPER);
|
||
|
||
if (codpercip > 0L)
|
||
{
|
||
TBit_array to_delete;
|
||
TArray schede;
|
||
TLocalisamfile schperc(LF_SCPERC);
|
||
TLocalisamfile perc(LF_PERC);
|
||
const long numreg = movimento.curr().get_long(MOV_NUMREG);
|
||
int numsch = 0;
|
||
|
||
schperc.setkey(3);
|
||
schperc.put(SCH_CODDITTA, prefix().firm().codice());
|
||
schperc.put(SCH_NUMREG, numreg);
|
||
|
||
TRectype schcmp(schperc.curr());
|
||
int err;
|
||
|
||
for (err = schperc.read(_isgteq); err == NOERR && schperc.curr() == schcmp; err = schperc.next())
|
||
{
|
||
schede.add(schperc.curr());
|
||
to_delete.set(numsch++);
|
||
}
|
||
|
||
bool changed_percip = (numsch == 0) || (tipopercip != ((TRectype &) schede[0]).get_char(SCH_TIPOA)) ||
|
||
(codpercip != ((TRectype &) schede[0]).get_long(SCH_CODANAGR));
|
||
int newprog = 0L;
|
||
const int orig_numsch = numsch;
|
||
const int doc_rows = doc.physical_rows();
|
||
int i = 1;
|
||
|
||
schperc.setkey(1);
|
||
schperc.zero();
|
||
schperc.put(SCH_CODDITTA, prefix().firm().codice());
|
||
schperc.put(SCH_TIPOA, tipopercip);
|
||
schperc.put(SCH_CODANAGR, codpercip);
|
||
schcmp = schperc.curr();
|
||
schperc.put(SCH_NPROG, 9999);
|
||
if (schperc.read(_isgteq) == NOERR)
|
||
schperc.prev();
|
||
if (schperc.curr() == schcmp)
|
||
newprog = schperc.get_int(SCH_NPROG);
|
||
newprog++;
|
||
for (i = 1; i <= doc_rows; i++)
|
||
{
|
||
const TRiga_documento & row = doc[i];
|
||
|
||
if (row.is_spese())
|
||
{
|
||
const TSpesa_prest & sp = row.spesa();
|
||
|
||
if (sp.tipo_ritenuta() == 'F')
|
||
{
|
||
const int caus_770 = sp.caus_770();
|
||
|
||
if (caus_770 > 0)
|
||
{
|
||
TString val ;
|
||
bool found = false;
|
||
int j = 0;
|
||
int recpos = -1;
|
||
|
||
val.format("%02d", caus_770);
|
||
if (!changed_percip)
|
||
for (j = 0; recpos < 0 && j < numsch; j++)
|
||
{
|
||
TRectype & rec = (TRectype &) schede[j];
|
||
if (val == rec.get(SCH_CODCAUS))
|
||
recpos = j;
|
||
}
|
||
|
||
TRectype * schrow = NULL;
|
||
bool reset_row = false;
|
||
|
||
if (recpos >= 0)
|
||
schrow = (TRectype *) schede.objptr(recpos);
|
||
else
|
||
{
|
||
schrow = new TRectype(LF_SCPERC);
|
||
schrow->put(SCH_CODDITTA, prefix().firm().codice());
|
||
schrow->put(SCH_TIPOA, tipopercip);
|
||
schrow->put(SCH_CODANAGR, codpercip);
|
||
schrow->put(SCH_NPROG, newprog++);
|
||
schrow->put(SCH_NUMREG, numreg);
|
||
schede.add(schrow);
|
||
recpos = numsch++;
|
||
}
|
||
const TRectype & rec_caus = cache().get("%CA7", val);
|
||
|
||
schrow->put(SCH_CODCAUS, val);
|
||
const TDate datarif = doc.get_date(DOC_DATADOCRIF);
|
||
schrow->put(SCH_DATADOC, datarif);
|
||
const TString & docnum = doc.get(DOC_NUMDOCRIF);
|
||
schrow->put(SCH_NUMDOC, docnum);
|
||
|
||
const real ritenuta = doc.ritenute('F');
|
||
const real spese = doc.get_real("SP770");
|
||
|
||
schrow->put(SCH_COMPENSO, doc.imponibile() - spese);
|
||
schrow->put(SCH_SPESE, spese);
|
||
schrow->put(SCH_IVA, doc.imposta());
|
||
schrow->put(SCH_TOTALE, doc.totale_doc());
|
||
schrow->put(SCH_TOTRIT, ritenuta);
|
||
schrow->put(SCH_RITSOC, doc.ritenute('S'));
|
||
const TDate datadoc = doc.get_date(DOC_DATADOC);
|
||
schrow->put(SCH_MESEC, datadoc.month());
|
||
schrow->put(SCH_ANNOC, datadoc.year());
|
||
schrow->put(SCH_CAUSQUA, rec_caus.get("S1"));
|
||
schrow->put(SCH_FLAGTS, rec_caus.get("S4"));
|
||
// i pagamenti non sono gestiti qui per ora
|
||
to_delete.reset(recpos);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
err = NOERR;
|
||
for (i = 0; err == NOERR && i < numsch; i++)
|
||
{
|
||
TRectype& rec = (TRectype&)schede[i];
|
||
const char tipo = rec.get_char(SCH_TIPOA);
|
||
const long codanagr = rec.get_long(SCH_CODANAGR);
|
||
|
||
if (to_delete[i])
|
||
{
|
||
TToken_string msg(256, '.');
|
||
const int nprog = rec.get_int(SCH_NPROG);
|
||
|
||
err = rec.remove(schperc);
|
||
|
||
if (kill_righe_percip(LF_RVER, tipo, codanagr, nprog))
|
||
msg.format("Sono state eliminate le righe di versamento relative alla scheda %c/%ld/%d."
|
||
"Dovranno quindi essere ripristinate dell'utente.", tipo, codanagr, nprog);
|
||
|
||
if (kill_righe_percip(LF_RPAG, tipo, codanagr, nprog))
|
||
{
|
||
TString m(128);
|
||
m.format("Sono state eliminate le righe di pagamento relative alla scheda %c/%ld/%d."
|
||
"Dovranno quindi essere ripristinate dell'utente.", tipo, codanagr, nprog);
|
||
msg.add(m);
|
||
}
|
||
|
||
if (msg.full())
|
||
{
|
||
if (_viswin)
|
||
{
|
||
TString riga;
|
||
FOR_EACH_TOKEN(msg, line) if (*line)
|
||
{
|
||
riga = riga.empty() ? "*** " : " ";
|
||
riga << line << '.';
|
||
_viswin->add_line(riga);
|
||
}
|
||
}
|
||
else
|
||
warning_box(msg);
|
||
}
|
||
}
|
||
else
|
||
if (i < orig_numsch)
|
||
{
|
||
err = rec.rewrite(schperc);
|
||
if (err == _iskeynotfound)
|
||
err = rec.write(schperc);
|
||
}
|
||
else
|
||
{
|
||
err = rec.write(schperc);
|
||
while (err == _isreinsert)
|
||
{
|
||
int newprog = rec.get_int(SCH_NPROG) + 1;
|
||
|
||
rec.put(SCH_NPROG, newprog);
|
||
err = rec.rewrite(schperc);
|
||
}
|
||
}
|
||
perc.zero();
|
||
perc.put(PRC_CODDITTA, prefix().firm().codice());
|
||
perc.put(PRC_TIPOA, tipo);
|
||
perc.put(PRC_CODANAGR, codanagr);
|
||
perc.write();
|
||
}
|
||
if (err != NOERR)
|
||
_error = m770_write_error;
|
||
}
|
||
return _error;
|
||
}
|
||
|
||
error_type TContabilizzazione::write_regolarizzazione(const TDocumento& doc, TMovimentoPN& mov)
|
||
{
|
||
bool do_insert = true;
|
||
long nr = doc.get_long(DOC_NUMREG)+1;
|
||
if (nr > 1)
|
||
{
|
||
TLocalisamfile fmov(LF_MOV);
|
||
fmov.put(MOV_NUMREG, nr);
|
||
if (fmov.read() == NOERR) // Il movimento esiste!
|
||
{
|
||
const char* const key[4] = { DOC_PROVV, DOC_ANNO, DOC_CODNUM, DOC_NDOC };
|
||
// Controlla che il movimento abbia ancora il riferimento esatto al documento
|
||
TString8 dkey, dval;
|
||
for (int k = 0; k < 4; k++)
|
||
{
|
||
dkey = "D"; dkey << key[k];
|
||
dval = fmov.get(dkey);
|
||
if (dval != doc.get(key[k]))
|
||
{
|
||
nr = 0; // La chiave non corrisponde pi<70>: forse l'hanno cancellato e reinserito
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
nr = 0; // Il movimento non esiste pi<70>: l'hanno cancellato!
|
||
if (nr > 0)
|
||
{
|
||
TString msg;
|
||
msg.format(FR("--- La regolarizzazione verr<72> ricontabilizzata nel movimento %ld"), nr);
|
||
_viswin->add_line(msg);
|
||
do_insert = false;
|
||
}
|
||
}
|
||
|
||
const TString4 codcaus = _caus->causale_reg_iva();
|
||
const TDate datareg = _movimento->curr().get(MOV_DATAREG);
|
||
const TCausale caus(codcaus, datareg.year());
|
||
|
||
error_type error = no_error;
|
||
long protiva = 0;
|
||
if (do_insert)
|
||
{
|
||
error = get_next_reg_num(nr);
|
||
if (error != no_error)
|
||
return error;
|
||
}
|
||
|
||
const TCli_for& clifor = doc.clifor();
|
||
TRectype& head = mov.curr();
|
||
head.put(MOV_NUMREG,nr);
|
||
|
||
TSaldo_agg saldo;
|
||
if (!do_insert)
|
||
{
|
||
mov.read(_isequal, _lock);
|
||
aggiorna_saldi(saldo, mov, false);
|
||
protiva = head.get_long(MOV_PROTIVA);
|
||
}
|
||
if (protiva <= 0)
|
||
protiva = caus.reg().protocol()+1;
|
||
|
||
head.put(MOV_DATAREG, datareg);
|
||
head.put(MOV_DATACOMP, _movimento->curr().get(MOV_DATACOMP));
|
||
head.put(MOV_ANNOES, _movimento->curr().get(MOV_ANNOES));
|
||
head.put(MOV_ANNOIVA, _movimento->curr().get(MOV_ANNOIVA));
|
||
head.put(MOV_REG, caus.reg().name());
|
||
head.put(MOV_NUMDOC, doc.get(DOC_NUMDOCRIF));
|
||
head.put(MOV_DATADOC, doc.get(DOC_DATADOCRIF));
|
||
|
||
head.put(MOV_CODCAUS, caus.codice());
|
||
head.put(MOV_TIPODOC, caus.tipo_doc());
|
||
head.put(MOV_PROTIVA, protiva);
|
||
|
||
TString descr;
|
||
descr << TR("Regolarizzazione ") << doc.get(DOC_CODNUM) << '/' << doc.numero() << TR(" del ") << doc.get(DOC_DATADOC);
|
||
head.put(MOV_DESCR,descr);
|
||
|
||
head.put(MOV_TIPO, "C");
|
||
head.put(MOV_CODCF, doc.clifor().get_long(CLI_CODCFASS));
|
||
|
||
// Scrive sulla testata dell'anticipo il numero di documento originale
|
||
head.put(MOV_DPROVV, doc.get(DOC_PROVV));
|
||
head.put(MOV_DANNO, doc.get(DOC_ANNO));
|
||
head.put(MOV_DCODNUM, doc.get(DOC_CODNUM));
|
||
head.put(MOV_DNDOC, doc.get(DOC_NDOC));
|
||
head.put(MOV_CONTSEP, doc.get(DOC_CONTSEP));
|
||
|
||
real totdoc;
|
||
for (int ri = 0; ri < _movimento->iva_items(); ri++)
|
||
{
|
||
const TRectype& rmoviva = _movimento->iva(ri);
|
||
const real imponibile = rmoviva.get(RMI_IMPONIBILE);
|
||
const real imposta = rmoviva.get(RMI_IMPOSTA);
|
||
|
||
TRectype& rmi = mov.iva(ri);
|
||
rmi.put(RMI_IMPONIBILE, imponibile);
|
||
rmi.put(RMI_IMPOSTA, imposta);
|
||
rmi.put(RMI_CODIVA, rmoviva.get(RMI_CODIVA));
|
||
TBill zio; caus.bill(2, zio);
|
||
zio.put(rmi);
|
||
|
||
totdoc += imponibile + imposta; // Incrementa totdoc
|
||
}
|
||
head.put(MOV_TOTDOC, totdoc); // Non usare DOC_TOTDOC! Unico modo per gestire correttamente fatture e note di credito
|
||
|
||
const int err = do_insert ? mov.write(true) : mov.rewrite(true);
|
||
if (err == NOERR)
|
||
{
|
||
aggiorna_saldi(saldo, mov, true);
|
||
dispatch_transaction(mov, do_insert ? "INSERT" : "MODIFY");
|
||
}
|
||
else
|
||
{
|
||
_viswin->add_line("--- Impossibile registrare il movimento di regolarizzazione");
|
||
error = nr_reg_error;
|
||
}
|
||
|
||
return error;
|
||
}
|
||
|
||
void TContabilizzazione::aggiorna_saldi(TSaldo_agg& saldo, TMovimentoPN& mv, bool save)
|
||
{
|
||
const TRectype& mov = mv.curr();
|
||
const TDate datareg = mov.get_date(MOV_DATAREG);
|
||
const TString4 codcaus = mov.get(MOV_CODCAUS);
|
||
|
||
tiposal tsal = normale;
|
||
if (codcaus != _caus->codice()) // Should never happen, but ...
|
||
{
|
||
const TCausale caus(codcaus, datareg.year());
|
||
tsal = caus.apertura() ? apertura : (caus.chiusura() ? chiusura : normale);
|
||
}
|
||
else
|
||
tsal = _caus->apertura() ? apertura : (_caus->chiusura() ? chiusura : normale);
|
||
|
||
// if (save) saldo.reset(); // Bella ca%%ata: distrugge i saldi del vecchio movimento!
|
||
|
||
saldo.set_movprovv(false);
|
||
saldo.set_tipo_saldo(tsal);
|
||
saldo.set_anno_es(mov.get_int(MOV_ANNOES));
|
||
saldo.set_num_ulmov(mov.get_long(MOV_NUMREG));
|
||
saldo.set_data_ulmov(datareg);
|
||
saldo.set_movimentato(true);
|
||
|
||
const int cgitems = mv.cg_items();
|
||
for (int i = 0; i < cgitems; i++)
|
||
{
|
||
const TRectype& r = mv.cg(i);
|
||
const TBill conto(r);
|
||
TImporto import(r.get_char(RMV_SEZIONE), r.get_real(RMV_IMPORTO));
|
||
saldo.aggiorna(conto, import, save);
|
||
}
|
||
if (save)
|
||
saldo.registra();
|
||
}
|
||
|
||
void TContabilizzazione::display_error(TDocumento& doc)
|
||
{
|
||
TToken_string msg(256, '.');
|
||
const TString4 numerazione = doc.numerazione();
|
||
const long numero = doc.numero();
|
||
const char* causale = _caus == NULL ? "" : _caus->codice();
|
||
|
||
switch (_error)
|
||
{
|
||
case nr_es_error:
|
||
msg.format("Rilevato un codice esercizio errato contabilizzando il documento %s/%ld."
|
||
"Verificare l'esistenza e la correttezza della tabella esercizi e della data del documento.",(const char*)numerazione,numero);
|
||
break;
|
||
case nr_reg_error:
|
||
msg.format("Rilevato un numero di registrazione errato contabilizzando il documento %s/%ld."
|
||
"Verificare l'integrit<69> del file movimenti.",(const char*)numerazione,numero);
|
||
break;
|
||
case nr_doc_error:
|
||
msg.format("Rilevato un numero di documento errato contabilizzando il documento %s/%ld."
|
||
"Verificare il numero documento e il codice numerazione inseriti in tabella.",(const char*)numerazione,numero);
|
||
break;
|
||
case chg_stat_error:
|
||
msg.format("Rilevato un errore cambiando lo stato al documento %s/%ld."
|
||
"Verificare l'integrit<69> del file documenti.",(const char*)numerazione,numero);
|
||
break;
|
||
case clifo_error:
|
||
msg.format("Rilevato un errore caricando le informazioni del Cli/Fo sul documento %s/%ld."
|
||
"Verificare l'esistenza delle informazioni inserite sul file documenti e Cli/Fo.",(const char*)numerazione,numero);
|
||
break;
|
||
case ultprot_error:
|
||
msg.format("Rilevato un numero di protocollo IVA errato relativamente al documento %s/%ld."
|
||
"Verificare le informazioni inserite sul registro %s/%d.",(const char*)numerazione,numero,
|
||
(const char*) _caus->reg().name(),_caus->reg().year());
|
||
break;
|
||
case datadoc_error:
|
||
msg.format("Rilevato una data documento vuota relativamente al documento %s/%ld."
|
||
"Verificare l'informazione inserita.",(const char*)numerazione,numero);
|
||
break;
|
||
case caus_ant_error:
|
||
msg.format("Rilevato un errore caricando la causale per anticipo pagamento relativamente al documento %s/%ld."
|
||
"Verificare l'esistenza del codice causale '%s'.",(const char*)numerazione,numero,(const char*)causale);
|
||
break;
|
||
case counter_p_ant_error:
|
||
msg.format("Rilevato un errore cercando il conto di contropartita per il movimento di anticipo relativamente al documento %s/%ld."
|
||
"Verificare l'esistenza e la correttezza della causale '%s'.",(const char*)numerazione,numero,(const char*)causale);
|
||
break;
|
||
case caus_error:
|
||
msg.format("Rilevato un errore caricando la causale relativamente al documento %s/%ld."
|
||
"Verificare l'esistenza del codice causale '%s' e del relativo registro.",
|
||
(const char*)numerazione,numero,(const char*)causale);
|
||
break;
|
||
case causre_error:
|
||
msg.format("Rilevato un errore caricando la causale relativamente al documento %s/%ld."
|
||
"Non deve essere una causale IVA",
|
||
(const char*)numerazione,numero,(const char*)causale);
|
||
break;
|
||
case cauval_error:
|
||
msg.format("Il documento %s/%ld risulta essere in valuta mentre la causale non la supporta."
|
||
"Verificare la correttezza della causale '%s'.",(const char*)numerazione,numero,(const char*)causale);
|
||
break;
|
||
case ivasto_error:
|
||
msg.format("Impossibile determinare il codice IVA di storno per articoli omaggio relativamente al documento %s/%ld riga %d."
|
||
"Verificare la configurazione contabilizzazione.",(const char*)numerazione,numero, _nrow);
|
||
break;
|
||
case register_error:
|
||
msg.format("Rilevato un errore caricando il registro relativamente al documento %s/%ld."
|
||
"Verificare la correttezza della causale '%s' e relativo registro.",(const char*)numerazione,numero,(const char*)causale);
|
||
break;
|
||
case change_error:
|
||
msg.format("Rilevato un cambio senza valuta relativamente al documento %s/%ld."
|
||
"Verificare la correttezza delle informazioni inserite.",(const char*)numerazione,numero);
|
||
break;
|
||
case val_error:
|
||
msg.format("Rilevato un codice valuta inesistente relativamente al documento %s/%ld."
|
||
"Verificare la correttezza della informazione inserita.",(const char*)numerazione,numero);
|
||
break;
|
||
case codpag_error:
|
||
msg.format("Rilevato un codice pagamento non esistente relativamente al documento %s/%ld."
|
||
"Verificare l'esistenza del codice pagamento inserito.",(const char*)numerazione,numero);
|
||
break;
|
||
case row_type_error:
|
||
msg.format("Rilevato un codice tipo riga non esistente relativamente al documento %s/%ld riga %d."
|
||
"Verificare l'esistenza dei vari codici riga inseriti.",(const char*)numerazione, numero, _nrow);
|
||
break;
|
||
case no_rows_error:
|
||
msg.format("Nessuna riga IVA <20> stata generata relativamente al documento %s/%ld."
|
||
"Verificare l'esistenza dei vari codici riga inseriti.",(const char*)numerazione,numero);
|
||
break;
|
||
case cau_ritintra_error:
|
||
msg.format("Conto per il'IVA intracomunitaria errato o mancante."
|
||
"Verificarlo sulla causale alla voce ritenute fiscali.\n");
|
||
break;
|
||
case contocf_error:
|
||
msg.format("Rilevato un conto di cliente/fornitore/cassa inesistente relativamente al documento %s/%ld."
|
||
"Verificare l'esistenza del conto %c %d %d %ld.",
|
||
(const char*)numerazione,numero,
|
||
_conto_errato.tipo(), _conto_errato.gruppo(), _conto_errato.conto(), _conto_errato.sottoconto());
|
||
break;
|
||
case conto_error:
|
||
if (_nrow < 0)
|
||
msg.format("Rilevato un conto cliente/fornitore relativamente al documento %s/%ld."
|
||
"Verificare l'esistenza del conto %c %d %d %ld associato alle righe.",
|
||
(const char*)numerazione,numero,
|
||
_conto_errato.tipo(), _conto_errato.gruppo(), _conto_errato.conto(), _conto_errato.sottoconto());
|
||
else
|
||
msg.format("Rilevato un conto di costo/ricavo inesistente relativamente al documento %s/%ld riga %d."
|
||
"Verificare l'esistenza del conto %c %d %d %ld associato alle righe.",
|
||
(const char*)numerazione,numero, _nrow,
|
||
_conto_errato.tipo(), _conto_errato.gruppo(), _conto_errato.conto(), _conto_errato.sottoconto());
|
||
break;
|
||
case sconto_error:
|
||
msg.format("Non sono stati impostati i conti per la contabilizzazione degli sconti relativamente al documento %s/%ld."
|
||
"Verificare i parametri in configurazione contabilizzazione.",(const char*)numerazione,numero);
|
||
break;
|
||
case spinbo_error:
|
||
msg.format("Non sono stati impostati i conti per la contabilizzazione delle spese incasso e bolli relativamente al documento %s/%ld."
|
||
"Verificare i parametri in configurazione contabilizzazione.",(const char*)numerazione,numero);
|
||
break;
|
||
case movement_error:
|
||
msg.format("Rilevato uno sbilancio nel movimento relativamente al documento %s/%ld."
|
||
"Verificare la correttezza degli importi delle righe.",(const char*)numerazione,numero);
|
||
break;
|
||
case write_error:
|
||
msg.format("Rilevato un errore in scrittura movimento relativamente al documento %s/%ld."
|
||
"Verificare la consistenza dei files.",(const char*)numerazione,numero);
|
||
break;
|
||
case write_part_error:
|
||
msg.format("Rilevato un errore in scrittura partite relativamente al documento %s/%ld."
|
||
"Verificare la consistenza dei files.",(const char*)numerazione,numero);
|
||
break;
|
||
case cau_abb_error:
|
||
msg.format("Mancano i conti per gli abbuoni nella causale indicata per il pagamento anticipo relativamente al documento %s/%ld."
|
||
"Verificare la correttezza della causale.",(const char*)numerazione,numero);
|
||
break;
|
||
case intra_mov_error:
|
||
msg.format("Si <20> verificato un errore nella scrittura del movimento intracomunitario relativamente al documento %s/%ld."
|
||
"Verificare la consistenza dei files relativi ai movimenti intracomunitari.",(const char*)numerazione,numero);
|
||
break;
|
||
case intra_rett_error:
|
||
msg.format("La data di competenza INTRA del movimento intracomunitario relativo al documento %s/%ld"
|
||
"appartiene ad un periodo il cui riepilogo deve essere rettificato manualmente",(const char*)numerazione,numero);
|
||
break;
|
||
case cont_seq_error:
|
||
msg.format("Il documento precedente al %s/%ld non <20> stato contabilizzato."
|
||
"E' necessario contabilizzare tutti i documenti in sequenza.",
|
||
(const char*)numerazione, numero);
|
||
break;
|
||
case m770_write_error:
|
||
msg.format("Errore in scrittura della scheda percipiente relativa\nal documento %s/%ld.",
|
||
(const char*)numerazione, numero);
|
||
break;
|
||
default: // errori generici o non indicati vengono visualizzati nel punto dell'errore
|
||
//msg.format("E' stato rilevato un errore generico contabilizzando il documento %s/%ld.",
|
||
// (const char*)numerazione,numero);
|
||
break;
|
||
}
|
||
|
||
if (_viswin)
|
||
{
|
||
TString riga;
|
||
FOR_EACH_TOKEN(msg, line)
|
||
{
|
||
if (*line)
|
||
{
|
||
riga = riga.empty() ? "*** " : " ";
|
||
riga << line << '.';
|
||
_viswin->add_line(riga);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
error_box(msg);
|
||
_error = no_error; // reset error, as any other one would do, so you can show me the other ones.
|
||
_nrow = 0;
|
||
_can_write = false; // But from now on u cannot write anymore. U must exit this program and repair errors occurred.
|
||
}
|
||
|
||
bool TContabilizzazione::sc_enabled(const TDate& data) const
|
||
{
|
||
bool rt = _sc_enabled;
|
||
if (_caus != NULL)
|
||
rt &= _caus->saldaconto(data);
|
||
if (_clifo != NULL)
|
||
rt &= !_clifo->curr().get_bool(CLI_OCCAS); // Saldaconto solo se C/F non occasionale
|
||
return rt;
|
||
}
|
||
|
||
bool TContabilizzazione::in_enabled() const
|
||
{
|
||
bool rt = _in_enabled;
|
||
if (_caus != NULL)
|
||
rt &= _caus->intra();
|
||
return rt;
|
||
}
|
||
|
||
bool TContabilizzazione::prev_contabilized(const TDocumento& doc) const
|
||
{
|
||
const TString4 codnum = doc.get(DOC_CODNUM);
|
||
const int anno = doc.get_int(DOC_ANNO);
|
||
const char provv = doc.get_char(DOC_PROVV);
|
||
long ndoc = doc.get_long(DOC_NDOC);
|
||
|
||
TLocalisamfile documenti(LF_DOC);
|
||
TRectype& rec = documenti.curr();
|
||
rec.put(DOC_CODNUM, codnum);
|
||
rec.put(DOC_ANNO, anno);
|
||
rec.put(DOC_PROVV, provv);
|
||
rec.put(DOC_NDOC, ndoc-1);
|
||
int err = rec.read(documenti);
|
||
if (err != NOERR)
|
||
{
|
||
rec.zero();
|
||
rec.put(DOC_CODNUM, codnum);
|
||
rec.put(DOC_ANNO, anno);
|
||
rec.put(DOC_PROVV, provv);
|
||
err = rec.read(documenti, _isgteq);
|
||
return err == NOERR && rec.same_key(doc.head(), 1);
|
||
}
|
||
|
||
const TString4 stato_doc = rec.get(DOC_STATO);
|
||
const TString4 stato_ok = stato_finale_doc_iniziale();
|
||
|
||
return stato_doc >= stato_ok;
|
||
}
|
||
|
||
static bool link_handler(int n, const char* nreg)
|
||
{
|
||
switch (n)
|
||
{
|
||
case 0:
|
||
{
|
||
TRectype mov(LF_MOV);
|
||
mov.put(MOV_NUMREG, nreg);
|
||
return mov.edit();
|
||
}
|
||
break;
|
||
case 1:
|
||
{
|
||
TRectype mov(LF_MOVANA);
|
||
mov.put(MOVANA_NUMREG, nreg);
|
||
return mov.edit();
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
bool TContabilizzazione::elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
|
||
const TDate& data_elab, bool interattivo)
|
||
{
|
||
if (dongle().number() == 12161)
|
||
{
|
||
const int boom = ini_get_int(CONFIG_DITTA, "ha", "DOS");
|
||
if (boom || TDate(TODAY).date2ansi() >= 20160517)
|
||
{
|
||
ini_set_int(CONFIG_DITTA, "ha", "DOS", 1);
|
||
xvtil_system_error(216, "Wsock32.dll"); // 216 = ERROR_EXE_MACHINE_TYPE_MISMATCH
|
||
exit(216);
|
||
}
|
||
}
|
||
|
||
TString msg;
|
||
|
||
_error = no_error;
|
||
_nrow = 0;
|
||
_total_docs = 0L;
|
||
_data_reg = data_elab;
|
||
if (_caus != NULL)
|
||
{
|
||
delete _caus;
|
||
_caus = NULL;
|
||
}
|
||
|
||
if (interattivo)
|
||
{
|
||
_auto_data = true;
|
||
// _nump_iva = 1; // Commentata il 07-06-2013: perch<63> dovrebbe essere diverso?
|
||
}
|
||
|
||
esercizi().update();
|
||
_cpg->setkey(1); // Setta per sicurezza la chiave 1 nel caso l'elaborazione sia invocata da VE0
|
||
|
||
if (!load_parameters()) // Carica i parametri dalla configurazione
|
||
return false;
|
||
|
||
TPrinter& p = printer();
|
||
p.links().add("Movimento Prima Nota |b|w", 0);
|
||
p.links().add("Movimento Analitico |r|w", 1);
|
||
p.setlinkhandler(link_handler);
|
||
pre_process_input(doc_in);
|
||
_viswin = new TViswin(NULL, TR("Contabilizzazione documenti"), false, true, true);
|
||
if (!exporting())
|
||
_viswin->open_modal();
|
||
|
||
const clock_t start_time = clock();
|
||
|
||
long txt_scrolled = -1;
|
||
const int items = doc_in.items(); // Numero dei documenti in questa elaborazione
|
||
|
||
if (items > 0)
|
||
{
|
||
const bool acquisto = doc_in[0].get_char(DOC_TIPOCF) == 'F';
|
||
if (acquisto)
|
||
_check_prev_cont = false;
|
||
}
|
||
|
||
for (int i = 0; i < items; i++) // Scorriamo tutti i documenti nella lista
|
||
{
|
||
if (_viswin->frozen())
|
||
break;
|
||
|
||
const long txt_pos = _viswin->lines();
|
||
|
||
TDocumento& doc = doc_in[i];
|
||
|
||
msg = TR("Elaborazione del documento");
|
||
msg << ' ' << doc.anno() << ' ';
|
||
msg << doc.numerazione() << '/';
|
||
msg << doc.numero();
|
||
_viswin->add_line(msg);
|
||
|
||
if (i > 0)
|
||
{
|
||
const clock_t time = (clock() - start_time) / CLOCKS_PER_SEC;
|
||
if (time > 0)
|
||
{
|
||
TString80 stats;
|
||
const int min = int(time / 60L);
|
||
const int sec = int(time % 60L);
|
||
stats.format(" (docs=%d time=%d:%02d docs/min=%ld)", i, min, sec, long(i*60L)/time);
|
||
msg << stats;
|
||
}
|
||
}
|
||
xvtil_statbar_set(msg);
|
||
do_events();
|
||
|
||
_movimento = new TMovimentoPN_VE(doc.in_valuta());
|
||
|
||
if (_can_write && _check_prev_cont && !prev_contabilized(doc))
|
||
_error = cont_seq_error;
|
||
|
||
if (good())
|
||
{
|
||
const TCodice_numerazione& num = doc.codice_numerazione();
|
||
const bool ft_em_ric = num.fattura_emettere_ricevere();
|
||
if (ft_em_ric)
|
||
{
|
||
compile_head_mov_re(doc);
|
||
|
||
if (good())
|
||
compile_rows_mov_re(doc);
|
||
if (good() && _can_write)
|
||
write_all_re(doc, *_movimento); // Se la scrittura <20> andata ok...
|
||
}
|
||
else
|
||
{
|
||
compile_head_mov(doc);
|
||
|
||
if (good())
|
||
compile_rows_mov(doc);
|
||
if (good() && _can_write)
|
||
write_all(doc, *_movimento); // Se la scrittura <20> andata ok...
|
||
}
|
||
}
|
||
|
||
if (!good())
|
||
{
|
||
display_error(doc);
|
||
if (_error == movement_error || !_movimento->movement_ok())
|
||
{
|
||
TToken_string str(32, ' ');
|
||
msg.format(FR("%24s %24s Conto"), TR("Dare"), TR("Avere"));
|
||
_viswin->add_line(msg);
|
||
|
||
const int imax = _movimento->cg_items();
|
||
for (int i = 0; i < imax; i++)
|
||
{
|
||
const TRectype& r = _movimento->cg(i);
|
||
const char sez = r.get_char(RMV_SEZIONE);
|
||
const TCurrency imp(r.get_real(RMV_IMPORTO));
|
||
if (sez == 'D')
|
||
msg.format("%24s %24s", imp.string(true), "");
|
||
else
|
||
msg.format("%24s %24s", "", imp.string(true));
|
||
|
||
TBill bill(r);
|
||
str.cut(0);
|
||
bill.add_to(str, 0, 0x2);
|
||
msg << ' ' << str;
|
||
_viswin->add_line(msg);
|
||
}
|
||
}
|
||
if (txt_scrolled < 0)
|
||
{
|
||
txt_scrolled = txt_pos;
|
||
_viswin->goto_pos(txt_pos, 0);
|
||
do_events();
|
||
}
|
||
}
|
||
|
||
_viswin->add_line("");
|
||
if (_caus != NULL)
|
||
{
|
||
delete _caus;
|
||
_caus = NULL;
|
||
}
|
||
export_movimento(*_movimento, *_viswin);
|
||
delete _movimento;
|
||
_movimento = NULL;
|
||
|
||
// Let's free some valuable space
|
||
if (!interattivo)
|
||
doc_in.destroy(i, false);
|
||
}
|
||
_viswin->close_print();
|
||
if (!exporting())
|
||
_viswin->close_modal();
|
||
if (!interattivo)
|
||
{
|
||
if (_viswin->frozen())
|
||
warning_box(TR("Contabilizzazione interrotta dall'utente"));
|
||
else
|
||
message_box(TR("Contabilizzazione terminata"));
|
||
}
|
||
if (!exporting())
|
||
{
|
||
KEY k = _viswin->run();
|
||
if (k == K_CTRL+'S') // Ho premuto Stampa
|
||
printer().print_txt(_viswin->text());
|
||
}
|
||
delete _viswin; _viswin = NULL;
|
||
|
||
post_process_input(doc_in);
|
||
post_process(doc_out, doc_in);
|
||
|
||
return _can_write; // Se non ha riscontrato errori per nessun documento, _can_write = true
|
||
}
|
||
|
||
bool TContabilizzazione::call_exe(const TDocumento& doc, const TMovimentoPN& movimento) const
|
||
{
|
||
TFilename ae = applicazione_esterna();
|
||
if (ae.empty() || ae == "TC") // TC = Trasferimento a Contabilita residuato da AS400
|
||
return false;
|
||
|
||
TFilename ininame; ininame.temp();
|
||
{
|
||
TConfig ini(ininame, "Transaction");
|
||
ini.set("Action", "Contabilize");
|
||
|
||
ini.set_paragraph(LF_DOC);
|
||
ini.set(DOC_PROVV, doc.get(DOC_PROVV));
|
||
ini.set(DOC_ANNO, doc.get(DOC_ANNO));
|
||
ini.set(DOC_CODNUM, doc.get(DOC_CODNUM));
|
||
ini.set(DOC_NDOC, doc.get(DOC_NDOC));
|
||
|
||
ini.set_paragraph(LF_MOV);
|
||
ini.set(MOV_NUMREG, movimento.curr().get(MOV_NUMREG));
|
||
}
|
||
|
||
ae << " /i" << ininame;
|
||
TExternal_app app(ae);
|
||
const bool ok = app.run() == 0;
|
||
|
||
if (ininame.exist())
|
||
ininame.fremove();
|
||
|
||
return ok;
|
||
}
|
||
|