campo-sirio/ve/velib04b.cpp

4393 lines
137 KiB
C++
Raw Normal View History

#include <diction.h>
#include <dongle.h>
#include <execp.h>
#include <modaut.h>
#include <tabutil.h>
#include <printer.h>
#include <viswin.h>
#include "velib04.h"
#include "../ca/calib01.h"
#include <comuni.h>
#include <unloc.h>
#include <mov.h>
#include <rmov.h>
#include <rmoviva.h>
#include <clifo.h>
#include <cfven.h>
#include <nditte.h>
#include <occas.h>
#include <scadenze.h>
#include <doc.h>
#include <rdoc.h>
#include "velib.h"
#include "../cg/cg2103.h"
#include "../cg/cglib02.h"
#include "../cg/cgsaldac.h"
#include "../in/inlib01.h"
#include "../mg/anamag.h"
#include "../ca/movana.h"
#include "../m770/scperc.h"
#include "../m770/rpag.h"
#include "../m770/rver.h"
#include "../m770/perc.h"
#include <comuni.h>
#include <unloc.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)
{
CHECK(_caus,"Orgggssbb..._caus pointer is NULL!");
bool dare = false;
if (row_type == 'S')
dare = _caus->sezione_ritsoc() == '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++)
{
TRectype& s = cg(i);
const char t = s.get_char(RMV_ROWTYPE);
if (t == tipo)
{
const int gr = s.get_int(RMV_GRUPPO);
const int co = s.get_int(RMV_CONTO);
const long so = s.get_long(RMV_SOTTOCONTO);
const TBill c(gr,co,so);
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++)
{
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 e' 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);
}
rec.put(RMV_SEZIONE,imp.sezione());
rec.put(RMV_IMPORTO,imp.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')
{
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);
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
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
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'e' 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 andra' l'imponibile
if (newpos < 0) // conto non esistente: da inserire
{
const TString 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'e' imposta ...
{
int newposiva = type2pos('D');
const TImporto val(real2imp(iva, 'I'));
if (newposiva < 0)
{
int ri;
TBill contoiva;
const TRectype & head = lfile().curr();
if (head.get_bool(MOV_LIQDIFF))
_caus->bill(ri = RIGA_IVA_DIFFERITA, contoiva);
if (!contoiva.ok())
_caus->bill(ri = RIGA_IVA_DETRAIBILE, contoiva);
const TString80 d(_caus->desc_agg(ri));
if (contoiva.ok())
newposiva = set_cg_rec(-1, val, contoiva, d, 'D');
}
else
add_cg_rec(newposiva, val);
}
if (!ivaind.is_zero()) // Se c'e' imposta ...
{
int newposiva = type2pos('N');
const TImporto val(real2imp(ivaind, 'I'));
if (newposiva < 0)
{
const TString80 d(_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, d, '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)
{
TRectype& cur = cg(i);
bool inserted_row = FALSE;
TBill c;
const int gr = cur.get_int(RMV_GRUPPO);
const int co = cur.get_int(RMV_CONTO);
const long so = cur.get_long(RMV_SOTTOCONTO);
c.set(gr,co,so);
TBill cp;
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, forzera' la riga totale documento a cio' 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_items();
const TRectype& head = curr();
set_caus(&caus);
for (int i=0; i<righe; 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
{
real ritfis = head.get_real(MOV_RITFIS);
if (ritfis != 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;
}
real ritsoc = head.get_real(MOV_RITSOC);
if (ritsoc != 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;
}
}
if (_caus->tipomov() == 1) // Elimina eventuali righe vuote dalle fatture
{
for (int c = cg_items()-1; c >= 0; c--)
{
const TImporto imp = get_cg_imp(c);
if (imp.is_zero())
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 e' abilitato
static bool _in_enabled; // se true l'intra e' 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 e' valida come stringa
// di ricerca.
static TString16 _ivasto; // Codice IVA 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 = 1.0);
error_type add(const TRiga_documento * r, const TBill& conto, const int ndec = ALL_DECIMALS, const real & p = 1.0) { 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 = 1.0);
error_type add_omaggi(const TRiga_documento * r, const TBill& conto, const int ndec = ALL_DECIMALS, const real & p = 1.0) { 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 (_ivasto.empty())
return ivasto_error;
add(r, conto, ndec, p);
TRiga_documento r_storno(r);
r_storno.set_tipo("01");
r_storno.put(RDOC_CODIVA, _ivasto);
real prezzo = r_storno.get_real(RDOC_PREZZO);
prezzo = -prezzo;
r_storno.put(RDOC_PREZZO, prezzo);
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();
TString80 key;
const TCodiceIVA& tiva = r.iva();
TString16 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;
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));
key.format("%d|%-4s|%c|%3d|%3d|%6ld|%s",
ord,(const char*)cod,c.tipo(),c.gruppo(),c.conto(),c.sottoconto(), (const char *) tipodet);
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);
}
real val = iva->get_real(RMI_IMPONIBILE);
val += impon;
iva->put(RMI_IMPONIBILE, val);
iva->put(RMI_TIPODET, tipodet);
val = iva->get_real(RMI_IMPOSTA);
val += imposta;
iva->put(RMI_IMPOSTA, val);
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;
}
TContabilizzazione::TContabilizzazione(const char* cod)
: TElaborazione(cod), _auto_data(false)
{
_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");
_can_write = true;
_error = no_error;
_nrow = 0;
_total_docs = 0L;
_caus = NULL;
}
TContabilizzazione::TContabilizzazione(const TRectype& rec)
: TElaborazione(rec), _auto_data(false), _viswin(NULL)
{
_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");
_can_write = true;
_error = no_error;
_nrow = 0;
_total_docs = 0L;
_caus = NULL;
}
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())
{
error_box("Non e' abilitata alcuna ricerca per il conto di costo/ricavo in configurazione.");
return false;
}
_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");
_ivasto = conf.get("IVASTO","ve");
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 = _movimento->lfile();
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
{
long nreg = doc.get_long(anticipo ? DOC_NUMANT : DOC_NUMREG);
if (nreg > 0)
{
// NON usare la cache qui!!!!!!!!!!!!!!!!!!!!!!
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
const char* const key[4] = { DOC_PROVV, DOC_ANNO, DOC_CODNUM, DOC_NDOC };
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!
}
return nreg;
}
TCausale * TContabilizzazione::get_caus(const TDocumento& doc, const int year)
{
TString16 codcaus;
TToken_string key;
if (!_fld_cms_cont.blank())
{
const TString & cms = doc.commessa_principale();
if (!cms.blank())
{
key.add(cms);
const TString16 fld_val = cache().get(LF_COMMESSE, key, _fld_cms_cont);
if (!fld_val.blank())
{
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...
}
return codcaus.blank() ? NULL : new TCausale(codcaus, year);
}
error_type TContabilizzazione::compile_head_mov(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);
}
if (mov.get_bool(MOV_STAMPATO))
{
msg << "stampato sul giornale";
_viswin->add_line(msg);
}
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!
// Istanzia la causale del documento corrente...
const TTipo_documento& tipo = doc.tipo();
TString16 codcaus = tipo.causale();
TToken_string key;
key.add(doc.get(DOC_TIPOCF));
key.add(doc.get(DOC_CODCF));
const TRectype& cfven = cache().get(LF_CFVEN, key);
const TString& caus_cli = cfven.get(doc.is_nota_credito() ? CFV_CODCAUSNC : CFV_CODCAUS);
if (caus_cli.not_empty())
codcaus = caus_cli; // La causale del cliente prevale su quella del tipo documento
_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);
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
TString descr; doc.riferimento(descr);
if (descr.empty()) descr = tipo.descrizione();
const TString8 rif = doc.get(DOC_NUMDOCRIF);
const bool use_rif = _caus->iva() == iva_acquisti && rif.not_empty();
if (use_rif)
{
descr << TR(" n. ") << rif;
descr << TR(" del ") << doc.get(DOC_DATADOCRIF);
}
else
{
descr << TR(" n. ") << doc.numero();
descr << TR(" del ") << datadoc;
}
// Codice registro IVA
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 == 1) // 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
TDate datacam(doc.get_date(DOC_DATACAMBIO));
real cambio(doc.cambio());
TString4 codval(doc.valuta());
codval.trim();
if (!doc.in_valuta())
{
codval = "";
cambio = ZERO;
}
if (codval.not_empty())
{
_val->put("CODTAB",codval);
if (_val->read() != NOERR)
{
_error = val_error;
return _error;
}
}
// Reperisce il cambio
if ((cambio != ZERO && codval.empty()) ||
cambio == ZERO && codval.not_empty())
{
_error = change_error;
return _error;
}
// Dati del cliente...
TString4 tipocf(doc.get(DOC_TIPOCF));
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.not_empty()) // 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)
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.not_empty())
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.not_empty() && codvali != codval)
{
mov_rec.put(MOV_CODVALI,codvali);
TExchange c(codvali);
cambioi = c.get_base_change();
mov_rec.put(MOV_CAMBIOI, cambioi);
}
else
{
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,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())
dataintra = d;
}
mov_rec.put(MOV_DATACOMPI, dataintra);
}
}
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 = 1.00;
}
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())
{
TDate d = doc.get_date(DOC_DATADOCRIF);
if (d.ok())
dataintra = d;
}
mov_rec.put(MOV_DATACOMPI, dataintra);
}
}
}
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));
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)
{
TString16 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!
// 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
TString descr; doc.riferimento(descr);
const TTipo_documento& tipo = doc.tipo();
if (descr.empty()) descr = tipo.descrizione();
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(DOC_DATADOCRIF);
descr << " del " << data_rif;
}
else
{
descr << " n. " << doc.numero();
descr << " del " << datadoc.string();
}
// 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));
return _error;
}
error_type TContabilizzazione::search_costo_ricavo(TBill& conto, const TRiga_documento& r)
{
const int items = _search_seq->items();
TLocalisamfile & cli_file = _clifo->lfile(); // YES, arriva qui dentro quando la relazione e' gia' posizionata
const bool is_cli = cli_file.get(CLI_TIPOCF) == "C";
bool skip_art_related = false;
bool skip_clifo = _clifo->bad();
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 artioli(3)+Categoria di vendita cliente(2)
TString8 cod = _anamag->get(ANAMAG_CATCONV);
cod << _clifo->curr(LF_CFVEN).get(CFV_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)
{
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)
row = i;
}
if (row > 0)
{
__searching = true;
search_costo_ricavo(conto, r.doc()[row]);
__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(real& spese, real& sp_iva, int ndec, bool is_incasso, bool is_cli, const TString & codiva_es, const TDocumento & doc)
{
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;
}
error_type TContabilizzazione::add_spese_inbo(TDocumento& doc, const int ndec)
// Aggiunge le righe di spese incasso/bolli
{
real tot_netto, sp_incasso, sp_bolli;
real iva_sp_incasso, iva_sp_bolli;
const real rit = doc.ritenute();
const bool is_cli = doc.get_char(DOC_TIPOCF) == 'C';
// Aggiunge le spese d'incasso
tot_netto = doc.totale_netto();
sp_incasso = doc.spese_incasso(tot_netto, ndec, _netto);
TString4 codiva_es;
doc.iva_esente(codiva_es);
if (!sp_incasso.is_zero())
calculate_spese(sp_incasso,iva_sp_incasso,ndec,true,is_cli, codiva_es.not_empty() ? codiva_es : doc.codiva_spese(), doc);
// Aggiunge le spese bolli
tot_netto += sp_incasso + iva_sp_incasso - rit;
sp_bolli = doc.bolli(tot_netto, ndec, _netto);
if (!sp_bolli.is_zero())
calculate_spese(sp_bolli, iva_sp_bolli, ndec, false, is_cli, 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, 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();
const exchange_type et = doc.get_bool(DOC_CONTROEURO) ? _exchange_contro : _exchange_base;
// 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, et);
iva_g *= cam.get_base_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.not_empty())
{
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
{
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 lire
{
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 != ZERO && codiva.not_empty())
{
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_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();
}
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();
static TString_array tabella_ripartizione;
if (fat_com && tabella_ripartizione.empty())
{
TConfig cnf(CONFIG_STUDIO);
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
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;
TBill 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); // l'errore eventuale viene settato qui dentro
if (good())
{
static TString16 fldvalmat("883");
if (fldvalmat == "883")
{
TConfig c(CONFIG_DITTA, "ve");
fldvalmat = c.get("FldValMat", "");
}
if (fldvalmat.full())
{
pricemat = real(cache().get(LF_ANAMAG, r.get(RDOC_CODARTMAG), fldvalmat));
if (pricemat != 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);
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
_righe_iva->add(r, conto);
}
if (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 (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));
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)
{
static int __check_sez = 2;
if (__check_sez > 1)
{
TConfig c(CONFIG_DITTA, "ve");
__check_sez = c.get_bool("CHECK_SEZ", false);
}
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 TString4 sez = rec_cg.get(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();
_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);
if ((tipo != RIGA_DESCRIZIONI && tipo != RIGA_SCONTI && tipo != RIGA_RETTIFICHE) && !riga_omaggio)
{
TBill conto;
search_costo_ricavo(conto,r); // l'errore eventuale viene settato qui dentro
if (good())
_righe_iva->add(r, conto);
}
}
else
{
_error = row_type_error;
_nrow = i;
}
}
if (good() && _righe_iva->items() == 0)
_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)
// Scrive le scadenze. Liberamente tratto da cg2104.cpp.
{
const TRectype& head = _movimento->curr();
const long nreg = head.get_long(MOV_NUMREG);
// const real change(head.get_real(MOV_CAMBIO));
int anno = head.get_int(MOV_ANNOIVA);
TString16 numpart = doc.get(DOC_NUMDOCRIF);
if (numpart.full() && _caus->iva() == iva_vendite && !doc.tipo().nota_credito())
numpart.cut(0);
if (numpart.blank())
{
numpart = head.get(_nump_cfg ? MOV_PROTIVA : MOV_NUMDOC);
}
else
{
TDate ddr = doc.get_date(DOC_DATADOCRIF);
if (ddr.ok())
anno = ddr.year();
}
TPartita* newgame = NULL;
if (anno > 0 && !numpart.blank())
{
const int tmov = _caus->tipomov();
const TString80 desc(head.get(MOV_DESCR));
const TString16 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
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 = 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.lit2val(ti);
totimposte.set_num(ti);
}
const TCurrency totimponibili = td - totimposte - totspese;
TCurrency_documento anticipo(doc.get_real(DOC_IMPPAGATO), doc);
if (anticipo.abs() < td.abs())
{
TGeneric_distrib d(anticipo.get_num(), ndec);
d.add(totimponibili.get_num());
d.add(totimposte.get_num());
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 (totimposte.get_num() - 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;
// 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);
}
real imponibile, imponibile_val;
int i;
for (i = pag.n_rate()-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, imponibile_val);
partita.put(PART_IMPOSTA, imposte);
partita.put(PART_SPESE, totspese.get_num());
newgame->scollega_pagamenti(nuova_riga); // Sempre meglio che perderli, ma andrebbero ricollegati
partita.elimina_rata(-1); // Elimina tutte le rate eventuali
const TString8 abipr(doc.get(DOC_CODABIP)), cabpr(doc.get(DOC_CODCABP)),
abi(doc.get(DOC_CODABIA)), cab(doc.get(DOC_CODCABA));
const int nr = pag.n_rate();
const TString16 codpag(head.get(MOV_CODPAG));
for (i = 0; i < nr; i++)
{
TRiga_scadenze& scadenza = partita.new_row();
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 (doc.is_nota_credito())
{
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 TString16 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;
}
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();
}
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);
if (sc_enabled(head.get_date(MOV_DATAREG)))
write_scadenze(doc);
if (good() && in_enabled())
write_intra(doc);
if (good() && (dongle().active(CMAUT) || dongle().active(CAAUT)))
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);
if (doc.get_real(DOC_IMPPAGATO) != ZERO)
if (write_anticipo(doc) != 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();
TString80 msg;
msg.format("--- Movimento contabile $[b,w]%ld$[n,w]", mov.get_long(MOV_NUMREG));
msg << " del " << mov.get(MOV_DATAREG);
_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);
if (good() && (dongle().active(CMAUT) || dongle().active(CAAUT)))
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)
{
TString descr;
const TString16 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) ? "Saldo fattura" : "Acconto fattura";
descr << " n. " << doc.numero();
descr << " del " << doc.get_date(DOC_DATADOC).string();
head.put(MOV_DESCR,descr);
head.put(MOV_TIPOMOV,char(_caus->tipomov()+'0'));
head.zero(MOV_REG);
head.zero(MOV_PROTIVA);
head.zero(MOV_CODPAG);
head.zero(MOV_CORRLIRE);
head.zero(MOV_CORRVALUTA);
TString codval = head.get(MOV_CODVALI);
// real cambio = head.get_real(MOV_CAMBIOI);
head.zero(MOV_CODVALI);
head.zero(MOV_CAMBIOI);
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));
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)
{
TLocalisamfile& mov = _anticipo->lfile();
const int anno = mov.get_date(MOV_DATAREG).year();
TString 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();
TRiga_partite& riga_part = partita->new_row();
// 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,mov.get_long(MOV_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();
real cambio = doc.get_real(DOC_CAMBIO);
TString16 val(doc.get(DOC_CODVAL));
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:
// reperire il numero della riga partita (nrigp) appena aggiunta
int nriga = (int) TPartita::UNASSIGNED, nrigp = riga_part.get_int(PART_NRIGA);
// 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())
{
TString16 s1 = rpart.get(PART_NUMDOC); s1.trim();
TString16 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;
}
// 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;
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)
{
// 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...
_error = no_error;
_error = compile_head_anticipo(doc);
if (_error == no_error)
{
// 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;
if (doc_contabilized(doc, true))
{
TMovimentoPN oldant;
oldant.curr().put(MOV_NUMREG, doc.get(DOC_NUMANT));
if (oldant.read() == NOERR)
aggiorna_saldi(saldo, oldant, false);
err = _anticipo->rewrite();
}
else
err = _anticipo->write();
if (err != NOERR)
{
error_box("Errore %d scrivendo il movimento di anticipo pagamento %ld.",
err, _anticipo->curr().get_long(MOV_NUMREG));
return generic_error;
}
aggiorna_saldi(saldo, *_anticipo, true);
}
delete _anticipo;
_anticipo = NULL;
}
}
return _error;
}
error_type TContabilizzazione::write_intra(TDocumento& doc)
{
const TRectype& rm = _movimento->curr();
// Controllo la liceita' della scrittura del moviemnto intra
const TDate data_reg = rm.get(MOV_DATAREG);
TDate data_intra = rm.get(MOV_DATACOMPI);
if (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);
TString16 nomenclatura, ums, paeseorig, provincia, paese;
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();
paese = _clifo->lfile().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;
const int items = doc.physical_rows();
int numrig = 1;
for (int i=1; i<=items; i++)
{
const TRiga_documento& rr = doc[i];
if (rr.is_articolo())
{
const TRectype& rec_anamag = cchh.get(LF_ANAMAG, rr.get(RDOC_CODARTMAG));
nomenclatura = rec_anamag.get(ANAMAG_CLASSDOG);
ums = cchh.get("%NOC", nomenclatura, "S5");
massanun = rec_anamag.get_real(ANAMAG_MASSANUN); // Massa KG
unsuppun = rec_anamag.get_real(ANAMAG_UNSUPPUN); // Massa UMS
paeseorig = !is_cessione ? rec_anamag.get(ANAMAG_PAESE) : EMPTY_STRING; // Campo solo per Acquisti
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);
}
Patch level : 2.0 550 Files correlati : batbcaa.msk ve2.exe ve0.exe ve6.exe Ricompilazione Demo : [ ] Commento : PG200010 Il campo descrizione dell'articolo in lingua decodifica la tabella lingue e non permette quindi di inserire la descrizione dell'articolo stesso nella lingua stabilita PG200013 Variando il prezzo in immissione documento DI ACQUISTO non viene implementato il campo ultimo costo nell'anagrafica articoli: probabilmente dipende dall'errore generato (vedi errore n, 200017) che non permette di registrare le variazioni su anagrafiche articoli già inserite. PG200014 Nel caso di contabilizzazione di fatture provenienti da paesi cee il programma in fase di "elabora" segnala che manca il codice della provincia di origine all'interno dell'anagrafica articolo pur essendo detto campo correttamente inserito PG200017 La variazione di un qualsiasi campo all'interno di una anagrafica articoli in fase di registrazione genera un errore "I CODICI DELLE GIACENZE NON POSSONO ESSERE VUOTI" . PG200025 Nel caso di una nota di credito che storna totalmente una fattura emessa o ricevuta (e quindi la partita è chiusa) la procedura giustamnete non trova nulla. Nel caso invece di una nota di credito parziale su fattura con modalità di pagamento ad esempio 30/60/90 la procedura non considera affatto la nota di credito e propone gli importi lordi. Sarebbe utile dallo scadenzario poter chiudere le singole rate saldate dalla nota di credito e gestire il residuo della partita sulla/e rate restanti git-svn-id: svn://10.65.10.50/trunk@11369 c028cbd2-c16b-5b4b-a496-9718f37d4682
2003-08-04 15:08:30 +00:00
key.format(" |%s", (const char*)com);
provincia = cchh.get(LF_COMUNI, key, COM_PROVCOM);
}
if (nomenclatura.blank() || unsuppun.is_zero() || 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 (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);
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("UMS", ums);
rc->put("NOMENCL", nomenclatura);
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.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 ammlire = 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)
{
ammlire -= imp.get_num();
ammvaluta -= is_val ? imp_val.get_num() : ZERO;
}
else
{
ammlire += imp.get_num();
ammvaluta += is_val ? imp_val.get_num() : ZERO;
}
massakg += qta * massanun;
massaums += qta * unsuppun;
if (rr.exist("VALSTAT"))
{
TCurrency_documento vstat(rr.get_real("VALSTAT"), doc);
vstat.change_to_firm_val();
if (nota_credito)
valstat -= vstat.get_num();
else
valstat += vstat.get_num();
}
else
{
if (nota_credito)
valstat -= qta * rec_anamag.get_real(ANAMAG_VALSTATUN);
else
valstat += qta * rec_anamag.get_real(ANAMAG_VALSTATUN);
}
rc->put("AMMLIRE", ammlire);
rc->put("AMMVALUTA", ammvaluta);
rc->put("MASSAKG", massakg);
rc->put("MASSAUMS", massaums);
rc->put("VALSTAT", valstat);
if (nota_credito)
totale_righe -= imp.get_num(); // Il totale delle righe in Euro!
else
totale_righe += imp.get_num(); // Il totale delle righe in Euro!
}
}
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("TOTDOC", rm.get_real(MOV_TOTDOC));
intra.put("TOTDOCIMM", totale_righe);
if (_caus->valintra() && codvali.empty())
{
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);
Patch level : 2.0 550 Files correlati : batbcaa.msk ve2.exe ve0.exe ve6.exe Ricompilazione Demo : [ ] Commento : PG200010 Il campo descrizione dell'articolo in lingua decodifica la tabella lingue e non permette quindi di inserire la descrizione dell'articolo stesso nella lingua stabilita PG200013 Variando il prezzo in immissione documento DI ACQUISTO non viene implementato il campo ultimo costo nell'anagrafica articoli: probabilmente dipende dall'errore generato (vedi errore n, 200017) che non permette di registrare le variazioni su anagrafiche articoli già inserite. PG200014 Nel caso di contabilizzazione di fatture provenienti da paesi cee il programma in fase di "elabora" segnala che manca il codice della provincia di origine all'interno dell'anagrafica articolo pur essendo detto campo correttamente inserito PG200017 La variazione di un qualsiasi campo all'interno di una anagrafica articoli in fase di registrazione genera un errore "I CODICI DELLE GIACENZE NON POSSONO ESSERE VUOTI" . PG200025 Nel caso di una nota di credito che storna totalmente una fattura emessa o ricevuta (e quindi la partita è chiusa) la procedura giustamnete non trova nulla. Nel caso invece di una nota di credito parziale su fattura con modalità di pagamento ad esempio 30/60/90 la procedura non considera affatto la nota di credito e propone gli importi lordi. Sarebbe utile dallo scadenzario poter chiudere le singole rate saldate dalla nota di credito e gestire il residuo della partita sulla/e rate restanti git-svn-id: svn://10.65.10.50/trunk@11369 c028cbd2-c16b-5b4b-a496-9718f37d4682
2003-08-04 15:08:30 +00:00
if (intra.write() == _isreinsert) // Succede con le ricontabilizzazioni
intra.rewrite(); // si effettua una riscrittura
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;
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;
}
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 TString16 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 TString4 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'integrita' 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'integrita' 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 contabile e' stata trovata 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 e' 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)
{
TString msg;
_error = no_error;
_nrow = 0;
_total_docs = 0L;
_caus = NULL;
_data_reg = data_elab;
if (interattivo)
{
_auto_data = true;
_nump_iva = 1;
}
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];
Patch level : 2.0 512 Files correlati : ve6.exe ve6100a.msk Ricompilazione Demo : [ ] Commento : AO20061 Se sul tipo documento interessato per la contabilizzazione dello stesso ho selezionato il campo "Calcolo importi al lordo" non mi contabilizza nessun documento creato con questa modalità, appena tolgo il flag invece mi contabilizza tutto. ATTENZIONE: Non succede in generale, infatti nelle prove fatte funziona sempre. Ne deriva che occorrono importi ben precisi e quindi occorrono i dati specifici per ricreare la situazione di errore. Normalmente basta aumentare i decimali degli importi. AO20062 Per un tipo documento ho specificato "Calcolo importi al lordo"; spostandomi col TAB da un campo all'altro della riga di dettaglio mi toglie sempre il check da "Lordo", inoltre contrariamente alla vecchia versione tale campo degli Importi al Lordo non è più selezionabile tramite tastiera, ciò determina che una volta inserito il prezzo debba rispuntare col mouse tale campo, mentre una volta era sufficiente scorrere i campi col tab e mettere la 'X' quindi l'inserimento degli importi al lordo risultava molto più agevole. ATTENZIONE: Si tratta di una scelta operata con le nuove librerie. Occorre tavola rotonda e decisione al vertice per modificare questo comportamento. AO20063 Su Win98 se scelgo una stampante Generica / solo testo come dimensione carattere mi riporta solo 0. AO20066 Ho provato a stampare una fattura utilizzando il vecchio modulo bmp, in visualizzazione la stampa è corretta ma se lancio la stampa su foglio A4 non mi viene stampata la parte grafica; utilizzando invece il nuovo sfondo bmp esce tutto corretto (questo chiaramente è un errore che va ad influire anche sui vecchi moduli personalizzati); sulla 16bit invece con lo stesso modulo e stesso bmp, stampa corretto. git-svn-id: svn://10.65.10.50/trunk@11288 c028cbd2-c16b-5b4b-a496-9718f37d4682
2003-06-26 10:48:09 +00:00
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;
const TCodice_numerazione num(doc.numerazione());
const bool ft_em_ric = num.fattura_emettere_ricevere();
if (good())
{
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 e' andata ok...
}
else
{
compile_head_mov(doc);
if (good())
compile_rows_mov(doc);
if (good() && _can_write)
write_all(doc, *_movimento); // Se la scrittura e' 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");
TString8 para;
para.format("%d", LF_DOC);
ini.set_paragraph(para);
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));
para.format("%d", LF_MOV);
ini.set_paragraph(para);
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())
::remove(ininame);
return ok;
}