a0a36d6b33
Files correlati : Ricompilazione Demo : [ ] Commento : Riportata la versione 01.05 patch 282 git-svn-id: svn://10.65.10.50/trunk@8019 c028cbd2-c16b-5b4b-a496-9718f37d4682
2320 lines
78 KiB
C++
Executable File
2320 lines
78 KiB
C++
Executable File
#include <applicat.h>
|
||
#include <modaut.h>
|
||
#include <tabutil.h>
|
||
#include <progind.h>
|
||
|
||
#include <mov.h>
|
||
#include <rmov.h>
|
||
#include <rmoviva.h>
|
||
#include <clifo.h>
|
||
#include <cfven.h>
|
||
#include <occas.h>
|
||
#include <scadenze.h>
|
||
#include <doc.h>
|
||
#include <rdoc.h>
|
||
#include "../mg/anamag.h"
|
||
|
||
|
||
#include "velib.h"
|
||
#include "../cg/cg2101.h"
|
||
#include "../cg/cg2103.h"
|
||
#include "../cg/cgsaldac.h"
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TContabilizzazione
|
||
///////////////////////////////////////////////////////////
|
||
|
||
// TMovimentoPN_VE
|
||
// Classe derivata da TMovimentoPN per calcolare automaticamente le righe contabili
|
||
// una volta settate le righe iva e la riga di totale documento
|
||
// Sostanzialmente di tratta di aggiungere un metodo in piu' :
|
||
// recalc_cg_rows(), liberamente ispirato alla notify_iva() in cg2102.cpp
|
||
|
||
class TMovimentoPN_VE : public TMovimentoPN
|
||
{
|
||
TCausale * _caus;
|
||
bool _valuta;
|
||
|
||
protected:
|
||
// simula il K_SPACE di iva_notify
|
||
void create_row(int i);
|
||
// simula il K_ENTER di iva_notify
|
||
void enter_row(int i);
|
||
// verifica se si tratta di iva indetraibile
|
||
bool detraibile(TRectype& rec) const ;
|
||
// cerca la prima tra quelle di contabilita' che corrisponde al tipo indicato
|
||
int type2pos(char tipo);
|
||
// Trova nelle righe contabili un conto nelle righe di tipo prescelto
|
||
int bill2pos(const TBill& conto, char tipo);
|
||
// trasforma un real in TImporto, in base al tipo riga
|
||
TImporto real2imp(const real& r, char row_type);
|
||
// setta il record delle righe di contabilita'
|
||
int set_cg_rec(int n, const TImporto& imp, TBill& conto, const char* desc, char tipo);
|
||
// aggiunge l'importo indicato alla n-esima riga di contabilita'
|
||
bool add_cg_rec(int n, const TImporto& imp);
|
||
// Legge l'importo della riga n e lo ritorna col segno dovuto
|
||
TImporto get_cg_imp(int n);
|
||
// Setta l'importo della riga n
|
||
void set_cg_imp(int n, const TImporto& imp);
|
||
// verifica se il movimento e' quadrato oppure ha qualche maledetto sbilancio
|
||
// ritorna TRUE, ovviamente, se everything's alright.
|
||
bool movement_ok() ;
|
||
public:
|
||
// ricalcola le righe di contabilita' dalle righe iva presenti
|
||
// e verifica la quadratura del movimento. Ritorna TRUE se il movimento e' scrivibile
|
||
bool recalc_cg_rows(TCausale* caus = NULL);
|
||
TMovimentoPN_VE(bool valuta) : _valuta(valuta) {};
|
||
virtual ~TMovimentoPN_VE() {}
|
||
};
|
||
|
||
TImporto TMovimentoPN_VE::real2imp(const real& r, char row_type)
|
||
{
|
||
CHECK(_caus,"Orgggssbb..._caus pointer is NULL!");
|
||
bool dare;
|
||
if (row_type == 'S')
|
||
{
|
||
dare = _caus->sezione_ritsoc() == 'D';
|
||
}
|
||
else
|
||
{
|
||
dare = _caus->sezione_clifo() == 'D';
|
||
if (row_type != 'T' && row_type != 'F')
|
||
dare = !dare;
|
||
}
|
||
|
||
TImporto importo(dare ? 'D' : 'A', r);
|
||
return importo;
|
||
}
|
||
|
||
bool TMovimentoPN_VE::detraibile(TRectype& rec) const
|
||
{
|
||
CHECK(_caus,"Orgggssbb..._caus pointer is NULL!");
|
||
if (_caus->iva() == iva_vendite)
|
||
return TRUE;
|
||
|
||
if (rec.get_int(RMI_TIPODET) != 0)
|
||
return FALSE;
|
||
|
||
const int annodoc = curr().get_date(MOV_DATADOC).year();
|
||
const bool prorata100 = _caus->reg().prorata100(annodoc);
|
||
return !prorata100; // Se prorata = 100% e' indetraibile
|
||
}
|
||
|
||
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)
|
||
{
|
||
TBill c;
|
||
const int gr = s.get_int(RMV_GRUPPO);
|
||
const int co = s.get_int(RMV_CONTO);
|
||
const long so = s.get_long(RMV_SOTTOCONTO);
|
||
c.set(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)
|
||
{
|
||
TRectype& rec = cg(n);
|
||
TImporto importo;
|
||
const char sez = rec.get_char(RMV_SEZIONE);
|
||
const real valore(rec.get_real(RMV_IMPORTO));
|
||
importo.set(sez,valore);
|
||
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, 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 = 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));
|
||
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());
|
||
rec.put(RMV_TIPOC,conto.tipo());
|
||
rec.put(RMV_GRUPPO,conto.gruppo());
|
||
rec.put(RMV_CONTO,conto.conto());
|
||
rec.put(RMV_SOTTOCONTO,conto.sottoconto());
|
||
//rec.put(RMV_DESCR,conto.descrizione());
|
||
|
||
if (tipo == 'T') // Calcolo contropartita
|
||
{
|
||
TRectype& irec = iva(0);
|
||
const char t = irec.get_char(RMI_TIPOC);
|
||
const int gr = irec.get_int(RMI_GRUPPO);
|
||
const int co = irec.get_int(RMI_CONTO);
|
||
const long so = irec.get_long(RMI_SOTTOCONTO);
|
||
rec.put(RMV_TIPOCC,t);
|
||
rec.put(RMV_GRUPPOC,gr);
|
||
rec.put(RMV_CONTOC,co);
|
||
rec.put(RMV_SOTTOCONTOC,so);
|
||
}
|
||
else
|
||
{
|
||
const int pos = type2pos('T');
|
||
if (pos >= 0)
|
||
{
|
||
TRectype& crec = cg(pos);
|
||
const char t = crec.get_char(RMV_TIPOC);
|
||
const int gr = crec.get_int(RMV_GRUPPO);
|
||
const int co = crec.get_int(RMV_CONTO);
|
||
const long so = crec.get_long(RMV_SOTTOCONTO);
|
||
rec.put(RMV_TIPOCC,t);
|
||
rec.put(RMV_GRUPPOC,gr);
|
||
rec.put(RMV_CONTOC,co);
|
||
rec.put(RMV_SOTTOCONTOC,so);
|
||
}
|
||
}
|
||
|
||
rec.put(RMV_ROWTYPE,tipo);
|
||
return n;
|
||
}
|
||
|
||
void TMovimentoPN_VE::create_row(int i)
|
||
{
|
||
CHECK(_caus,"Orgggssbb..._caus pointer is NULL!");
|
||
TRectype& cur = iva(i);
|
||
real oldimp = cur.get_real(RMI_IMPONIBILE);
|
||
real oldiva = cur.get_real(RMI_IMPOSTA);
|
||
|
||
if (oldiva.is_zero() && _caus->corrispettivi()) // In caso di corrispettivi ...
|
||
{
|
||
const TString zanicchi(cur.get(RMI_CODIVA)); // Codice IVA
|
||
const TCodiceIVA i(zanicchi);
|
||
oldiva = i.scorpora(oldimp); // ... scorpora imposta dall'imponibile
|
||
}
|
||
|
||
const char tipod = detraibile(cur) ? 'D' : 'N';
|
||
|
||
if (type2pos(tipod) < 0 && !oldiva.is_zero())
|
||
{
|
||
const int ri = tipod == 'D' ? 3 : 4; // Calcola riga causale per l'IVA
|
||
TBill c; _caus->bill(ri, c);
|
||
if (c.ok())
|
||
{
|
||
const TString80 d(_caus->desc_agg(ri));
|
||
set_cg_rec(-1, real2imp(ZERO, 'I'), c, d, tipod);
|
||
}
|
||
else
|
||
if (ri == 4) // Se non esiste il conto IVA indetraibile ...
|
||
{ // ... somma imponibile e imposta
|
||
oldimp += oldiva;
|
||
oldiva = 0.0;
|
||
}
|
||
}
|
||
|
||
TBill oldconto;
|
||
const int gr = cur.get_int(RMI_GRUPPO);
|
||
const int co = cur.get_int(RMI_CONTO);
|
||
const long so = cur.get_long(RMI_SOTTOCONTO);
|
||
oldconto.set(gr,co,so);
|
||
if (oldconto.ok())
|
||
{
|
||
if (bill2pos(oldconto, 'I') < 0)
|
||
{
|
||
const TString d(_caus->desc_agg(2));
|
||
set_cg_rec(-1, real2imp(ZERO, 'I'), oldconto, d, 'I');
|
||
}
|
||
}
|
||
}
|
||
|
||
void TMovimentoPN_VE::enter_row(int i)
|
||
{
|
||
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);
|
||
|
||
if (imposta.is_zero() && _caus->corrispettivi()) // In caso di corrispettivi ...
|
||
{
|
||
const TString zanicchi(cur.get(RMI_CODIVA));
|
||
const TCodiceIVA i(zanicchi);
|
||
imposta = i.scorpora(imponibile); // ... scorpora imposta dall'imponibile
|
||
}
|
||
|
||
TBill conto;
|
||
const char t = cur.get_char(RMI_TIPOC);
|
||
const int gr = cur.get_int(RMI_GRUPPO);
|
||
const int co = cur.get_int(RMI_CONTO);
|
||
const long so = cur.get_long(RMI_SOTTOCONTO);
|
||
conto.set(gr,co,so,t);
|
||
|
||
int newpos = bill2pos(conto, 'I'); // Riga in cui andra' l'imponibile
|
||
|
||
const bool detrarre = detraibile(cur); // Determina se IVA detraibile
|
||
|
||
// Calcola riga causale col conto opportuno
|
||
const int ri = detrarre ? RIGA_IVA_DETRAIBILE : RIGA_IVA_NON_DETRAIBILE;
|
||
TBill contoiva; _caus->bill(ri, contoiva);
|
||
|
||
if (ri == 4 && !contoiva.ok()) // Se non c'e' il conto IVA indetraibile ...
|
||
{ // ... somma imponibile e imposta
|
||
imponibile += imposta;
|
||
imposta = 0.0;
|
||
}
|
||
|
||
// Aggiorna conto sulla riga contabile
|
||
if (newpos < 0) // conto non esistente: da inserire
|
||
{
|
||
const TImporto val(real2imp(imponibile, 'I'));
|
||
if (conto.ok() && !val.is_zero()) // Se c'e' imponibile ...
|
||
{ // crea una nuova riga contabile
|
||
const TString d(_caus->desc_agg(2));
|
||
set_cg_rec(-1, val, conto, d, 'I');
|
||
}
|
||
}
|
||
else
|
||
{
|
||
TImporto val(real2imp(imponibile, 'I'));
|
||
add_cg_rec(newpos, val);
|
||
}
|
||
|
||
// Aggiorna conto IVA sulla riga contabile
|
||
|
||
const char tipod = detrarre ? 'D' : 'N';
|
||
int newposiva = type2pos(tipod);
|
||
|
||
if (newposiva < 0)
|
||
{
|
||
if (!imposta.is_zero()) // Se c'e' imposta ...
|
||
{ // ... crea nuova riga per l'IVA
|
||
const TImporto val(real2imp(imposta, 'I'));
|
||
const TString d(_caus->desc_agg(ri));
|
||
set_cg_rec(-1, val, contoiva, d, tipod);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
const TImporto val(real2imp(imposta, 'I'));
|
||
add_cg_rec(newposiva, val);
|
||
}
|
||
}
|
||
|
||
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)
|
||
{
|
||
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 (!tot_imp.is_zero())
|
||
return FALSE;
|
||
return TRUE;
|
||
}
|
||
|
||
bool TMovimentoPN_VE::recalc_cg_rows(TCausale* caus)
|
||
{
|
||
const int righe = iva_items();
|
||
bool external_caus = TRUE;
|
||
if (caus == NULL)
|
||
{
|
||
external_caus = FALSE;
|
||
TRectype& head = lfile().curr();
|
||
TString16 codcau(head.get(MOV_CODCAUS));
|
||
int year = head.get_int(MOV_ANNOIVA);
|
||
_caus = new TCausale (codcau,year);
|
||
}
|
||
else
|
||
_caus = caus;
|
||
for (int i=0; i<righe; i++)
|
||
{
|
||
create_row(i);
|
||
enter_row(i);
|
||
}
|
||
if (!external_caus)
|
||
{
|
||
delete _caus;
|
||
_caus = NULL;
|
||
}
|
||
return movement_ok();
|
||
}
|
||
|
||
// TIVA_element
|
||
// classe di elementi da memorizzare nel TAssoc_array (vedi sotto) _righe_iva
|
||
class TIVA_element : public TObject
|
||
{
|
||
real _imp;
|
||
real _iva;
|
||
real _ali;
|
||
TString _cod_iva;
|
||
public:
|
||
real& imp() { return _imp;} // Imponibile
|
||
real& iva() { return _iva;} // Iva
|
||
real& ali() { return _ali;} // Aliquota %
|
||
TString& cod_iva() { return _cod_iva;}
|
||
void zero(){ _imp = 0.0; _iva = 0.0; _ali = 0.0; _cod_iva = "";}
|
||
virtual TObject* dup() const { return new TIVA_element(*this); }
|
||
TIVA_element& operator = (TIVA_element& a);
|
||
TIVA_element& add(const TRiga_documento& a, const bool sc, const int ndec);
|
||
TIVA_element() { zero(); }
|
||
~TIVA_element() {};
|
||
};
|
||
|
||
TIVA_element& TIVA_element::operator=(TIVA_element& a)
|
||
{
|
||
_imp = a.imp(); _iva = a.iva(); _ali = a.ali();
|
||
_cod_iva = a.cod_iva();
|
||
return *this;
|
||
}
|
||
|
||
TIVA_element& TIVA_element::add(const TRiga_documento& a, const bool sc, const int ndec)
|
||
// It's horrible, I know.
|
||
{
|
||
const TIVA& xx = a.iva();
|
||
if (!sc) // Al netto dello sconto
|
||
{
|
||
_imp += a.imponibile();
|
||
_iva += a.imposta();
|
||
}
|
||
else
|
||
{
|
||
real imponibile = a.importo(FALSE,FALSE,ndec); // Imponibile della riga al lordo dello sconto
|
||
_imp += imponibile;// Imponibile lorda
|
||
_iva += ::iva(imponibile,xx,ndec);// imposta calcolata sull'imponibile lorda
|
||
}
|
||
_ali = xx.aliquota();
|
||
_cod_iva = xx.codice();
|
||
return *this;
|
||
}
|
||
|
||
static TBill _sco_perc_bill, _sco_imp_bill, // Conti per gli sconti a percentuale ed importi (dalla configurazione)
|
||
_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 _contsclor; // Contabilizza sconti al netto o al lordo (sconti suddiviso per ogni contropartita)
|
||
static TString16 _ivasto; // Codice IVA per storno articoli Omaggio
|
||
static TEsercizi_contabili _esc; // Per sapere a quale esercizio appartiene il documento
|
||
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
|
||
|
||
TContabilizzazione::TContabilizzazione(const char* cod)
|
||
: TElaborazione(cod), _auto_data(FALSE), _nump_iva(2)
|
||
{
|
||
_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);
|
||
|
||
_cpg = new TTable("%CPG");
|
||
_tri = new TTable("%TRI");
|
||
_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");
|
||
}
|
||
|
||
TContabilizzazione::TContabilizzazione(const TRectype& rec)
|
||
: TElaborazione(rec), _auto_data(FALSE), _nump_iva(2)
|
||
{
|
||
_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);
|
||
|
||
_cpg = new TTable("%CPG");
|
||
_tri = new TTable("%TRI");
|
||
_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");
|
||
}
|
||
|
||
TContabilizzazione::~TContabilizzazione()
|
||
{
|
||
delete _clifo;
|
||
delete _cpg;
|
||
delete _tri;
|
||
delete _val;
|
||
delete _gmc;
|
||
delete _rfa;
|
||
delete _cve;
|
||
delete _cco;
|
||
delete _prs;
|
||
delete _spp;
|
||
delete _caa;
|
||
delete _cra;
|
||
delete _anamag;
|
||
delete _fcaus;
|
||
delete _frcaus;
|
||
delete _attiv;
|
||
delete _part;
|
||
delete _scad;
|
||
delete _pags;
|
||
delete _intra;
|
||
delete _rintra;
|
||
delete _occas;
|
||
delete _docfile;
|
||
delete _rdocfile;
|
||
}
|
||
|
||
bool TContabilizzazione::load_parameters()
|
||
{
|
||
TConfig conf(CONFIG_DITTA);
|
||
|
||
_search_seq = conf.get("RICERCACR","ve");
|
||
|
||
// 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.items() == 0)
|
||
{
|
||
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 = main_app().has_module(INAUT, CHK_DONGLE);
|
||
_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");
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
bool TContabilizzazione::test_swap()
|
||
{
|
||
const char sez = _caus->sezione_clifo();
|
||
const bool s = (_caus->reg().iva() == 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.empty())
|
||
{
|
||
mov.last();
|
||
nr = mov.get_long(MOV_NUMREG) + 1L;
|
||
if (mov.status() != NOERR || nr < 1)
|
||
_error = nr_reg_error;
|
||
}
|
||
return _error;
|
||
}
|
||
|
||
error_type TContabilizzazione::compile_head_mov(TDocumento& doc)
|
||
// Compila la testata
|
||
{
|
||
TLocalisamfile& mov = _movimento->lfile();
|
||
TRectype& mov_rec = mov.curr();
|
||
|
||
// Reperisce la data documento
|
||
TDate datadoc(doc.data());
|
||
const bool acquisto = doc.get_char(DOC_TIPOCF) == 'F';
|
||
if (acquisto)
|
||
{
|
||
TDate datarif(doc.get(DOC_DATADOCRIF));
|
||
if (datarif.ok())
|
||
datadoc = datarif;
|
||
}
|
||
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
|
||
TDate data_reg(_auto_data ? datadoc : _data_reg);
|
||
|
||
// reperisce il codice anno esercizio,
|
||
int cod_es = _esc.date2esc(data_reg);
|
||
if (cod_es <= 0)
|
||
{
|
||
_error = nr_es_error;
|
||
return _error;
|
||
}
|
||
|
||
// reperisce l'ultimo numero di registrazione disponibile
|
||
long numreg;
|
||
_error = get_next_reg_num(numreg);
|
||
if (_error != no_error)
|
||
return _error;
|
||
|
||
TCodice_numerazione cod_num(doc.numerazione());
|
||
// calcola il numero documento aggiungendo l'eventuale prefisso/postfisso.
|
||
TString numdoc(cod_num.complete_num(doc.numero()));
|
||
if (acquisto)
|
||
{
|
||
TString numdocrif(doc.get(DOC_NUMDOCRIF));
|
||
if (numdocrif.not_empty())
|
||
numdoc = numdocrif;
|
||
}
|
||
|
||
if (numdoc.empty() || cod_num.status() != NOERR)
|
||
{
|
||
_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();
|
||
const TString codcaus(tipo.causale());
|
||
_caus = new TCausale(codcaus,data_reg.year());
|
||
if (!_caus->ok())
|
||
{
|
||
_error = caus_error;
|
||
return _error;
|
||
}
|
||
|
||
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(tipo.riferimento());
|
||
if (descr.empty()) descr = tipo.descrizione();
|
||
descr << " n. " << doc.numero();
|
||
descr << " del " << datadoc.string();
|
||
|
||
// Codice registro IVA
|
||
TRegistro& registro = _caus->reg();
|
||
if (!registro.ok())
|
||
{
|
||
_error = register_error;
|
||
return _error;
|
||
}
|
||
|
||
long ult_prot;
|
||
if (_nump_iva == 1) // Reperisce l'ultimo numero di protocollo dal registro IVA
|
||
{
|
||
ult_prot = registro.protocol() +1;
|
||
if (ult_prot < 1)
|
||
{
|
||
_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));
|
||
TString codval(doc.valuta());
|
||
real cambio(doc.cambio());
|
||
codval.trim();
|
||
if (codval == "LIT")
|
||
{
|
||
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...
|
||
TString tipocf(doc.get(DOC_TIPOCF));
|
||
long codcf = doc.get_long(DOC_CODCF);
|
||
TString 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
|
||
{
|
||
_error = clifo_error;
|
||
return _error;
|
||
}
|
||
}
|
||
|
||
// Codice pagamento
|
||
TString codpag(doc.get(DOC_CODPAG));
|
||
if (sc_enabled() || 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);
|
||
mov_rec.put(MOV_DATADOC,datadoc);
|
||
if (registro.agenzia_viaggi()) mov_rec.put(MOV_DATA74TER,data_reg);
|
||
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_REG,registro.name());
|
||
mov_rec.put(MOV_PROTIVA,ult_prot); mov_rec.put(MOV_CODVAL,codval);
|
||
mov_rec.put(MOV_CAMBIO,cambio); mov_rec.put(MOV_TIPO,tipocf);
|
||
mov_rec.put(MOV_DATACAM,datacam);
|
||
mov_rec.put(MOV_CODCF,codcf); mov_rec.put(MOV_OCFPI,occas);
|
||
mov_rec.put(MOV_CODPAG,codpag);
|
||
if (_caus->intra())
|
||
{
|
||
mov_rec.put(MOV_CODVALI,codval);mov_rec.put(MOV_CAMBIOI,cambio);
|
||
real corrval(doc.imponibile());
|
||
real corrlire = corrval*cambio;
|
||
if (codval.not_empty() && codval != "LIT")
|
||
{
|
||
mov_rec.put(MOV_CORRLIRE,corrlire);
|
||
mov_rec.put(MOV_CORRVALUTA,corrval);
|
||
} else
|
||
mov_rec.put(MOV_CORRLIRE,corrval);
|
||
}
|
||
real totdocval(doc.totale_doc());
|
||
real totdoclit = totdocval * cambio;
|
||
if (codval.not_empty() && codval != "LIT")
|
||
{
|
||
mov_rec.put(MOV_TOTDOC,totdoclit);
|
||
mov_rec.put(MOV_TOTDOCVAL,totdocval);
|
||
} else
|
||
mov_rec.put(MOV_TOTDOC,totdocval);
|
||
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();
|
||
int gr,co;
|
||
long so;
|
||
|
||
switch (t)
|
||
{
|
||
case 'O': // righe omaggio come articoli spiaccicato identico (avranno imponibile 0)
|
||
case 'M': // righe di merce
|
||
{
|
||
// posiziona l'anagrafica sull'articolo specificato sulla ..iga
|
||
_anamag->put(ANAMAG_CODART,r.get(RDOC_CODART));
|
||
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;
|
||
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; // 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;
|
||
gr = _anamag->get_int(is_cli ? ANAMAG_GRUPPOV : ANAMAG_GRUPPOA);
|
||
co = _anamag->get_int(is_cli ? ANAMAG_CONTOV : ANAMAG_CONTOA);
|
||
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 = atoi(t->get("S1"));
|
||
co = atoi(t->get("S2"));
|
||
so = atol(t->get("S3"));
|
||
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;
|
||
TString 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)
|
||
{
|
||
gr = tab->get_int(is_cli ? "I3" : "I0");
|
||
co = tab->get_int(is_cli ? "I4" : "I1");
|
||
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;
|
||
TString cod(is_cve ? r.doc().get(DOC_CATVEN) : "");
|
||
if (cod.empty())
|
||
{
|
||
if (skip_clifo) continue; // se non aveva trovato il cliente salta al prossimo
|
||
cod = _clifo->lfile(LF_CFVEN).get(is_cve ? CFV_CATVEN : CFV_CODCATC);
|
||
}
|
||
t->put("CODTAB",cod);
|
||
if (t->read() == NOERR)
|
||
{
|
||
const bool x =(is_cve || is_cli);
|
||
gr = t->get_int(x ? "I3" : "I0");
|
||
co = t->get_int(x ? "I4" : "I1");
|
||
so = t->get_long(x ? "I5": "I2");
|
||
conto.set(gr,co,so);
|
||
}
|
||
if (conto.ok()) break;
|
||
}
|
||
}
|
||
break; // case 'M'
|
||
}
|
||
case 'P': // righe prestazione
|
||
case 'S': // righe spese
|
||
{
|
||
TTable* tab = t == 'P' ? _prs : _spp;
|
||
tab->put("CODTAB",r.get(RDOC_CODART));
|
||
if (tab->read()==NOERR)
|
||
{
|
||
gr = tab->get_int(is_cli ? "I0" : "I3");
|
||
co = tab->get_int(is_cli ? "I1" : "I4");
|
||
so = tab->get_long(is_cli ? "I2" : "I5");
|
||
conto.set(gr,co,so);
|
||
}
|
||
|
||
if (!conto.find() && t == 'P') // 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;
|
||
}
|
||
}
|
||
}
|
||
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() && !conto.find())
|
||
_error = conto_error;
|
||
return _error;
|
||
}
|
||
|
||
error_type TContabilizzazione::add_iva_row(const TBill& conto, const TRiga_documento& r, const int ndec)
|
||
// Aggiunge le righe iva all'assoc_array di raggruppamento
|
||
{
|
||
TIVA_element el_tmp;
|
||
const TIVA& tiva = r.iva();
|
||
TString cod(tiva.codice());
|
||
const char tipo = conto.tipo();
|
||
const int gr = conto.gruppo();
|
||
const int co = conto.conto();
|
||
const long so = conto.sottoconto();
|
||
TString key;
|
||
const char tipo_r = r.tipo().tipo();
|
||
const bool sconto_lordo = tipo_r != 'C' && _contsclor && _sco_perc_bill.ok();
|
||
bool exists;
|
||
int ord=0;
|
||
// Ordine con cui vengono immesse le righe IVA:
|
||
// merce, omaggi, prestazioni, spese, bolli/spese d'incasso, sconti.
|
||
|
||
switch (tipo_r)
|
||
{
|
||
case 'M':
|
||
ord = 1;
|
||
break;
|
||
case 'O':
|
||
ord = 2;
|
||
break;
|
||
case 'P':
|
||
ord = 3;
|
||
break;
|
||
case 'S':
|
||
ord = 4;
|
||
break;
|
||
default: break;
|
||
}
|
||
|
||
// Le righe di sconto ad importo o percentuale vanno saltate
|
||
if (tipo_r != 'C')
|
||
{
|
||
key.format("%d|%-4s|%c|%3d|%3d|%6ld",ord,(const char*)cod,tipo,gr,co,so);
|
||
exists = _righe_iva.is_key(key);
|
||
TIVA_element& el = (exists ? (TIVA_element&)_righe_iva[key] : el_tmp);
|
||
|
||
// 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
|
||
if (tipo_r == 'O')
|
||
{
|
||
if (_ivasto.empty())
|
||
{
|
||
_error = ivasto_error;
|
||
return _error;
|
||
}
|
||
|
||
const real imp_om = r.imponibile_omaggio();
|
||
|
||
// Aggiunge la riga "normale"
|
||
|
||
el.imp() += imp_om;
|
||
el.iva() += r.imposta();
|
||
el.ali() = tiva.aliquota();
|
||
el.cod_iva() = tiva.codice();
|
||
_righe_iva.add(key,el,exists);
|
||
|
||
// Aggiunge la riga di "compensazione" imponibile (segno meno)
|
||
TIVA tiva_sto(_ivasto);
|
||
key.format("%d|%-4s|%c|%3d|%3d|%6ld",ord,(const char*)_ivasto,tipo,gr,co,so);
|
||
exists = _righe_iva.is_key(key);
|
||
el_tmp.zero();
|
||
|
||
TIVA_element& el_om = (exists ? (TIVA_element&)_righe_iva[key] : el_tmp);
|
||
|
||
el_om.cod_iva() = _ivasto;
|
||
el_om.imp() += -imp_om; // Note negative sign on the left...
|
||
|
||
real iva_om = ::iva(imp_om,tiva_sto,ndec);// imposta: dovrebbe essere sempre ZERO; in caso contrario si avra' un movimento NON quadrato
|
||
el_om.iva() += iva_om; // Could of Been Should of Been Would of Been
|
||
el_om.ali() = tiva_sto.aliquota();
|
||
|
||
_righe_iva.add(key,el_om,exists);
|
||
}
|
||
else // Any other kind of row...
|
||
{
|
||
el.add(r,sconto_lordo,ndec); // Inserisce la riga IVA al netto o al lordo dello sconto
|
||
_righe_iva.add(key,el,exists); // Le righe di sconto le aggiorna dopo
|
||
}
|
||
}
|
||
|
||
if (sconto_lordo) // Se e' settato il flag di contabilizzare anche gli sconti merce
|
||
{
|
||
real sconto = - r.sconto(); // Imponibile dello sconto (positivo, quindi si cambia di segno)
|
||
if (sconto != ZERO) // Le righe Omaggio con Addebito IVA hanno comunque sconto ZERO!
|
||
{
|
||
real ivasc = ::iva(sconto,tiva,ndec);// imposta calcolata sullo sconto
|
||
key.format("6|%-4s|%c|%3d|%3d|%6ld",
|
||
(const char*)cod,
|
||
_sco_perc_bill.tipo(),
|
||
_sco_perc_bill.gruppo(),
|
||
_sco_perc_bill.conto(),
|
||
_sco_perc_bill.sottoconto());
|
||
|
||
el_tmp.zero();
|
||
exists = _righe_iva.is_key(key);
|
||
TIVA_element& el_sc = (exists ? (TIVA_element&)_righe_iva[key] : el_tmp);
|
||
el_sc.ali() = tiva.aliquota();
|
||
el_sc.cod_iva() = tiva.codice();
|
||
el_sc.imp() += sconto;
|
||
el_sc.iva() += ivasc;
|
||
_righe_iva.add(key,el_sc,exists); // Sostituisce od aggiunge la riga relativa allo sconto
|
||
}
|
||
}
|
||
return no_error;
|
||
}
|
||
|
||
void TContabilizzazione::calculate_spese(real& spese, real& sp_iva, int ndec, bool is_incasso, bool is_cli)
|
||
{
|
||
char tipo;
|
||
int gr,co;
|
||
long so;
|
||
const TBill& zio = is_incasso ? (is_cli ? _spin_billv : _spin_billa) : (is_cli ? _spbo_billv : _spbo_billa);
|
||
TIVA sp_cod(is_incasso ? _spin_cod : _spbo_cod);
|
||
TIVA_element el_tmp;
|
||
TString key;
|
||
|
||
if (zio.ok())
|
||
{
|
||
sp_iva = iva(spese,sp_cod,ndec);
|
||
tipo = zio.tipo();
|
||
gr = zio.gruppo();
|
||
co = zio.conto();
|
||
so = zio.sottoconto();
|
||
key.format("5|%-4s|%c|%3d|%3d|%6ld",(const char*)sp_cod.codice(),tipo,gr,co,so);
|
||
const bool exists = _righe_iva.is_key(key);
|
||
TIVA_element& el = (exists ? (TIVA_element&)_righe_iva[key] : el_tmp);
|
||
el.imp() = spese;
|
||
el.iva() = sp_iva;
|
||
el.ali() = sp_cod.aliquota();
|
||
_righe_iva.add(key,el,exists);
|
||
}
|
||
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;
|
||
bool is_cli = doc.get(DOC_TIPOCF) == "C";
|
||
// Aggiunge le spese d'incasso
|
||
tot_netto = doc.totale_netto();
|
||
sp_incasso = doc.spese_incasso(tot_netto,ndec,_netto);
|
||
if (sp_incasso != 0.0)
|
||
calculate_spese(sp_incasso,iva_sp_incasso,ndec,TRUE,is_cli);
|
||
|
||
// Aggiunge le spese bolli
|
||
tot_netto += sp_incasso + iva_sp_incasso;
|
||
sp_bolli = doc.bolli(tot_netto,ndec, _netto);
|
||
if (sp_bolli != 0)
|
||
calculate_spese(sp_bolli,iva_sp_bolli,ndec,FALSE,is_cli);
|
||
|
||
return _error;
|
||
}
|
||
|
||
// Aggiorna le righe di sconto (importo o a percentuale)
|
||
error_type TContabilizzazione::adjust_sconto_rows(TDocumento& doc)
|
||
{
|
||
TIVA_element el_tmp;
|
||
TAssoc_array& aa = doc.tabella_iva();
|
||
TRiepilogo_iva * riep;
|
||
TString cod,key; // Codice IVA corrente
|
||
real sconto,iva;
|
||
const int ndec = doc.in_valuta() ? 3 : 0;
|
||
|
||
if (!_sco_imp_bill.ok() || !_sco_perc_bill.ok())
|
||
{
|
||
_error = sconto_error;
|
||
return _error;
|
||
}
|
||
|
||
// 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 TIVA& codiva = riep->cod_iva();
|
||
cod = codiva.codice(); // Codice IVA
|
||
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;
|
||
TBill& conto = perc ? _sco_perc_bill : _sco_imp_bill;
|
||
sconto = perc ? riep->sconto_perc() : riep->sconto_imp();
|
||
iva = ::iva(sconto,codiva,ndec);
|
||
if (sconto != ZERO)
|
||
{
|
||
key.format("6|%-4s|%c|%3d|%3d|%6ld",(const char*)cod,
|
||
conto.tipo(),
|
||
conto.gruppo(),
|
||
conto.conto(),
|
||
conto.sottoconto());
|
||
const bool exists = _righe_iva.is_key(key);
|
||
// Aggiorna imponibile ed imposta all'elemento relativo
|
||
el_tmp.zero();
|
||
TIVA_element& el = exists ? (TIVA_element&)_righe_iva[key] : el_tmp;
|
||
el.imp() += sconto;
|
||
el.iva() += iva;
|
||
el.ali() = codiva.aliquota();
|
||
el.cod_iva() = cod;
|
||
_righe_iva.add(key,el,exists);
|
||
}
|
||
}
|
||
}
|
||
return no_error;
|
||
}
|
||
|
||
// "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;
|
||
TString cod; // Codice IVA corrente
|
||
const int items = _movimento->iva_items();// Numero di righe IVA
|
||
const bool in_valuta = doc.in_valuta();
|
||
const real cambio = doc.cambio();
|
||
real iva_gen,imponibile;
|
||
|
||
// 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())
|
||
{
|
||
cod = riep->cod_iva().codice(); // Codice IVA
|
||
iva_gen = riep->imposta();
|
||
|
||
if (in_valuta) // I documenti vanno sempre contabilizzati in lire
|
||
iva_gen *= cambio;
|
||
|
||
if (iva_gen < ZERO)
|
||
iva_gen.floor(0);
|
||
else
|
||
iva_gen.ceil(0);
|
||
|
||
TGeneric_distrib gd(iva_gen); // Instanzia il TGeneric_ditrib con la vera Imposta
|
||
// Adesso scorre tutte le righe IVA contabili con questo codice IVA
|
||
for (int i = 0; i < items; i++)
|
||
{
|
||
TRectype& ie = _movimento->iva(i);
|
||
if (ie.get(RMI_CODIVA) == cod) // Se il codice IVA e' uguale
|
||
gd.add(ie.get_real(RMI_IMPOSTA)); // Aggiunge al TGeneric_distrib l'imposta corrente
|
||
}
|
||
// 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) == cod) // Se il codice IVA e' uguale
|
||
ie.put(RMI_IMPOSTA,gd.get()); // Sostituisce l'imposta con quella ricalcolata al fine di avere tutto giusto
|
||
}
|
||
} // Visto che vengono restituiti nello stesso ordine in cui sono state chiamate le rispettive TGeneric_distrib::add()
|
||
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->lfile().curr();
|
||
int gr,co;
|
||
long so;
|
||
char tipo;
|
||
TToken_string key;
|
||
TString_array key_arr;
|
||
TString16 codiva;
|
||
TBill conto;
|
||
|
||
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;
|
||
|
||
_righe_iva.get_keys(key_arr);
|
||
key_arr.sort();
|
||
TIVA_element cur;
|
||
for (int i = 0, nr = 0; i < items; i++)
|
||
{
|
||
key = key_arr.row(i);
|
||
cur = (TIVA_element&) _righe_iva[key];
|
||
codiva = key.get(1);
|
||
tipo = key.get_char(2);
|
||
gr = key.get_int(3);
|
||
co = key.get_int(4);
|
||
so = atol(key.get(5));
|
||
conto.set(gr,co,so,tipo);
|
||
conto.find();
|
||
imponibile = cur.imp();
|
||
if (in_valuta) // I documenti vanno sempre contabilizzati in lire
|
||
{
|
||
imponibile = cur.imp() * cambio; // imponibile in lire
|
||
imponibile.round();
|
||
imposta = abs(imponibile) * cur.ali() / 100.0; // questa e' l'imposta ricalcolata
|
||
imposta.ceil();
|
||
if (imponibile < 0.0)
|
||
imposta = -imposta;
|
||
}
|
||
else
|
||
imposta = cur.iva();
|
||
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,conto.tipo_cr());
|
||
rec_iva.put(RMI_INTRA,_caus->intra());
|
||
rec_iva.put(RMI_TIPOC,conto.tipo());
|
||
rec_iva.put(RMI_GRUPPO,conto.gruppo());
|
||
rec_iva.put(RMI_CONTO,conto.conto());
|
||
rec_iva.put(RMI_SOTTOCONTO,conto.sottoconto());
|
||
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->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));
|
||
real totdoc(head.get_real(MOV_TOTDOC));
|
||
|
||
char rowtype = 'T';
|
||
TLocalisamfile& cli_file = _clifo->lfile();
|
||
TString16 tipocf(cli_file.get(CLI_TIPOCF));
|
||
const 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)
|
||
{
|
||
gruppo = _co_cliente.gruppo();
|
||
conto = _co_cliente.conto();
|
||
}
|
||
else
|
||
_error = conto_error;
|
||
|
||
TString descr;
|
||
descr = head.get(MOV_DESCR);// La descrizione della riga di totale documento la prende dalla testata
|
||
|
||
TRectype& first_iva_row = _movimento->iva(0);
|
||
const char tc = first_iva_row.get_char(RMI_TIPOC);
|
||
const int grc = first_iva_row.get_int(RMI_GRUPPO);
|
||
const int coc = first_iva_row.get_int(RMI_CONTO);
|
||
const long soc =first_iva_row.get_long(RMI_SOTTOCONTO);
|
||
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); // qui
|
||
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); rec_cg.put(RMV_DESCR,descr);
|
||
rec_cg.put(RMV_TIPOCC,tc); rec_cg.put(RMV_GRUPPOC,grc);
|
||
rec_cg.put(RMV_CONTOC,coc);rec_cg.put(RMV_SOTTOCONTOC,soc);
|
||
rec_cg.put(RMV_IMPORTO,totdoc); rec_cg.put(RMV_ROWTYPE,rowtype);
|
||
|
||
return _error;
|
||
}
|
||
|
||
error_type TContabilizzazione::compile_rows_mov(TDocumento& doc)
|
||
// Compila le righe
|
||
{
|
||
const int rows = doc.rows();
|
||
const int ndec = doc.in_valuta() ? 3 : 0;
|
||
_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];
|
||
TString16 tiporiga(r.get(RDOC_TIPORIGA));
|
||
_tri->put("CODTAB",tiporiga);
|
||
if (_tri->read() == NOERR) // controlla l'esistenza della riga
|
||
{
|
||
TBill conto;
|
||
const char tipo = r.tipo().tipo();
|
||
// Le righe omaggio senza addebito IVA vanno saltate
|
||
const bool riga_omaggio = r.get_bool(RDOC_ADDIVA) && tipo == 'O';
|
||
if ((tipo != 'D' && tipo != 'C') || riga_omaggio)
|
||
{
|
||
search_costo_ricavo(conto,r); // l'errore eventuale viene settato qui dentro
|
||
if (good())
|
||
add_iva_row(conto,r,ndec);
|
||
}
|
||
}
|
||
else
|
||
_error = row_type_error;
|
||
}
|
||
|
||
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);
|
||
|
||
// 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())
|
||
if (!_movimento->recalc_cg_rows(_caus))
|
||
_error = movement_error;
|
||
return _error;
|
||
}
|
||
|
||
error_type TContabilizzazione::change_doc_status(TDocumento& doc)
|
||
// Cambia lo stato del documento
|
||
{
|
||
doc.stato(get("S4")[0]);
|
||
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.
|
||
{
|
||
TRectype& head = _movimento->lfile().curr();
|
||
|
||
TPagamento& pag = doc.pagamento();
|
||
|
||
real totspese = doc.spese();
|
||
real totimposte = doc.imposta();
|
||
real totimponibili = doc.totale_doc() - totimposte - totspese;
|
||
const TString16 codval = head.get(MOV_CODVAL);
|
||
const bool valuta = codval.not_empty();
|
||
if (valuta)
|
||
{
|
||
const real change(head.get_real(MOV_CAMBIO));
|
||
//real val1 = totimponibili * change;
|
||
real val2 = totimposte * change;
|
||
real val3 = totspese * change;
|
||
real val1 = head.get_real(MOV_TOTDOC) - val2 - val3; // Cosi' corregge eventuali scompensi di poche lirette
|
||
pag.set_total_valuta( totimponibili, totimposte, totspese, change, val1, val2, val3, codval);
|
||
}
|
||
else
|
||
pag.set_total( totimponibili, totimposte, totspese );
|
||
pag.set_rate_auto( );
|
||
|
||
const long nreg = head.get_long(MOV_NUMREG);
|
||
const int anno = head.get_int(MOV_ANNOIVA);
|
||
const TString numpart(head.get(_nump_cfg ? MOV_PROTIVA : MOV_NUMDOC));
|
||
|
||
TPartita* newgame = NULL;
|
||
|
||
int nuova_riga = 0;
|
||
|
||
if (anno > 0 && !numpart.blank())
|
||
{
|
||
const int tmov = _caus->tipomov();
|
||
const TString desc(head.get(MOV_DESCR));
|
||
const TString codcaus(_caus->codice());
|
||
const TString 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);
|
||
const TString agente(doc.get(DOC_CODAG));
|
||
const char sezione = _movimento->cg(0).get_char(RMV_SEZIONE); // Dare/Avere
|
||
|
||
TBill clifo;
|
||
const char tipocf = head.get_char(MOV_TIPO);
|
||
const long codcf = head.get_long(MOV_CODCF);
|
||
clifo.set(0,0,codcf,tipocf);
|
||
newgame = new TPartita(clifo, anno, numpart);
|
||
|
||
const int row = newgame->prima_fattura(nreg); // Riga fattura di questo movimento
|
||
TRiga_partite& partita = row <= 0 ? newgame->new_row() : newgame->riga(row);
|
||
nuova_riga = partita.get_int(PART_NRIGA);
|
||
|
||
// put data on partita
|
||
partita.put(PART_TIPOMOV, tmov);
|
||
partita.put(PART_NREG, nreg);
|
||
partita.put(PART_NUMRIG, 1);
|
||
partita.put(PART_DATAREG, head.get_date(MOV_DATAREG));
|
||
partita.put(PART_DATADOC, head.get_date(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_long(MOV_PROTIVA));
|
||
partita.put(PART_SEZ, sezione);
|
||
|
||
const real totdoc(head.get_real(MOV_TOTDOC));
|
||
partita.put(PART_IMPTOTDOC, totdoc);
|
||
|
||
cambio.put(partita);
|
||
const bool in_valuta = cambio.in_valuta();
|
||
|
||
if (in_valuta)
|
||
{
|
||
const real totdocval(head.get_real(MOV_TOTDOCVAL));
|
||
partita.put(PART_IMPTOTVAL,totdocval);
|
||
}
|
||
|
||
real imponibile, imponibile_val;
|
||
for (int 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, pag.imposta());
|
||
partita.put(PART_SPESE, pag.spese());
|
||
|
||
const TString abipr(doc.get(DOC_CODABIP)),
|
||
cabpr(doc.get(DOC_CODCABP)),
|
||
abi(doc.get(DOC_CODABIA)),
|
||
cab(doc.get(DOC_CODCABA));
|
||
|
||
partita.elimina_rata(-1); // Elimina tutte le rate eventuali
|
||
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 (newgame != NULL) // Se non ho cancellato il numero partita ...
|
||
{
|
||
if (!newgame->write()) // Salva nuova partita
|
||
//error_box("Si e' verificato un errore scrivendo le scadenze del documento.");
|
||
_error = write_part_error;
|
||
delete newgame;
|
||
}
|
||
|
||
return _error;
|
||
}
|
||
|
||
error_type TContabilizzazione::write_all(TDocumento& doc)
|
||
// 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->lfile().curr();
|
||
long numreg = head.get_long(MOV_NUMREG);
|
||
if (test_swap())
|
||
{
|
||
const real totdoc = -head.get_real(MOV_TOTDOC);
|
||
const real totdocval = -head.get_real(MOV_TOTDOCVAL);
|
||
|
||
head.put(MOV_TOTDOC, totdoc);
|
||
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);
|
||
}
|
||
}
|
||
while (_movimento->write() == _isreinsert)
|
||
head.put(MOV_NUMREG,++numreg);
|
||
if (_movimento->status() != NOERR)
|
||
{
|
||
error_box("Errore %d scrivendo il movimento %ld.",_movimento->status(),numreg);
|
||
return generic_error;
|
||
}
|
||
if (sc_enabled())
|
||
write_scadenze(doc);
|
||
|
||
return no_error;
|
||
}
|
||
|
||
error_type TContabilizzazione::compile_head_anticipo(TDocumento& doc)
|
||
{
|
||
TString descr;
|
||
TString16 codcaus = doc.tipo().caus_anticipo();
|
||
long nr = 1L;
|
||
TDate datareg(_movimento->lfile().get_date(MOV_DATAREG));
|
||
|
||
if (get_next_reg_num(nr) != no_error)
|
||
return nr_reg_error;
|
||
|
||
if (!_caus->read(codcaus,datareg.year()))
|
||
return caus_ant_error;
|
||
|
||
_anticipo = new TMovimentoPN;
|
||
TRectype& head = _anticipo->lfile().curr();
|
||
head = _movimento->lfile().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())
|
||
{
|
||
real p(doc.get_real(DOC_IMPPAGATO));
|
||
real plit = p * cambio;
|
||
if (codval.not_empty() && codval != "LIT")
|
||
{
|
||
head.put(MOV_TOTDOC,plit);
|
||
head.put(MOV_TOTDOCVAL,p);
|
||
}
|
||
else
|
||
{
|
||
head.put(MOV_TOTDOC,p);
|
||
head.zero(MOV_TOTDOCVAL);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
head.zero(MOV_TOTDOC);
|
||
head.zero(MOV_TOTDOCVAL);
|
||
}
|
||
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(TString & catven)
|
||
{
|
||
_error = no_error;
|
||
TLocalisamfile& clifo = _clifo->lfile();
|
||
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
|
||
_co_cliente.codclifo() = codcf;
|
||
if (!_co_cliente.ok())
|
||
_error = clifo_error;
|
||
}
|
||
}
|
||
return _error;
|
||
}
|
||
|
||
error_type TContabilizzazione::search_counter_bill(TDocumento& doc)
|
||
{
|
||
_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())
|
||
{
|
||
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.
|
||
TString16 codpag(doc.get(DOC_CODPAG));
|
||
TString16 catven(doc.get(DOC_CATVEN));
|
||
if (search_clifo_bill(catven) == no_error && search_counter_bill(doc) == no_error)
|
||
{
|
||
const real importo = doc.get_real(DOC_IMPPAGATO);
|
||
TLocalisamfile& mov = _anticipo->lfile();
|
||
TDate datareg = mov.get_long(MOV_DATAREG);
|
||
TString16 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() ? "K" : " ");
|
||
c_rec.put(RMV_IMPORTO, importo);
|
||
|
||
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() ? "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);
|
||
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());
|
||
|
||
real impval;
|
||
real imp = doc.get_real(DOC_IMPPAGATO);
|
||
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();
|
||
if (valuta)
|
||
{
|
||
impval = imp;
|
||
imp *= cambio;
|
||
}
|
||
riga_part.put(PART_IMPORTO,imp);
|
||
riga_part.put(PART_IMPORTOVAL,impval);
|
||
riga_part.put(PART_IMPTOTDOC,imp);
|
||
riga_part.put(PART_IMPTOTVAL,impval);
|
||
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() && rpart.get(PART_NUMDOC) == numpart)
|
||
{
|
||
nriga = r;
|
||
break;
|
||
}
|
||
}
|
||
// 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 = valuta ? impval : imp;
|
||
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 = 0.0;
|
||
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)
|
||
riga_pagamento.put(PAGSCA_IMPORTO, ((real)(res*cambio)).round());
|
||
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' ? 10 : 9;
|
||
_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())
|
||
// ... il pagamento vero e proprio, scrivendo la partita e modificando
|
||
// il movimento se vi sono abbuoni
|
||
write_pagamento_anticipo(doc);
|
||
|
||
TLocalisamfile& head = _anticipo->lfile();
|
||
long numreg = head.get_long(MOV_NUMREG);
|
||
while (_anticipo->write() == _isreinsert)
|
||
head.put(MOV_NUMREG,++numreg);
|
||
|
||
if (_anticipo->status() != NOERR)
|
||
{
|
||
error_box("Errore %d scrivendo il movimento di anticipo pagamento %ld.",_anticipo->status(),numreg);
|
||
return generic_error;
|
||
}
|
||
}
|
||
delete _anticipo;
|
||
_anticipo = NULL;
|
||
}
|
||
}
|
||
|
||
return _error;
|
||
}
|
||
|
||
error_type TContabilizzazione::write_intra(TDocumento& doc)
|
||
{
|
||
// 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 TRectype& rm = _movimento->lfile().curr();
|
||
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 int natura = doc.tipo().get_int("I2"); // natura della transazione, valida per tutte le righe del documento
|
||
const long numreg = rm.get_long(MOV_NUMREG);
|
||
TString16 nomenclatura, paeseorig, provincia, paese, codmag, commag;
|
||
real totale_righe;
|
||
const real cambio = doc.cambio();
|
||
const bool is_val = doc.in_valuta();
|
||
const bool is_cessione = rm.get(MOV_TIPO)=="C";
|
||
|
||
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())
|
||
{
|
||
key = "";
|
||
codmag = rr.get(RDOC_CODMAG);
|
||
const TRectype& rec_anamag = cchh.get(LF_ANAMAG, rr.get(RDOC_CODARTMAG));
|
||
commag = cchh.get("MAG", codmag, "S5"); // Comune del magazzino
|
||
nomenclatura = rec_anamag.get(ANAMAG_CLASSDOG);
|
||
paeseorig = !is_cessione ? rec_anamag.get(ANAMAG_PAESE) : ""; // Campo solo per Acquisti
|
||
provincia = is_cessione ? rec_anamag.get(ANAMAG_PROV) : cchh.get(LF_COMUNI, commag, "PROVCOM");
|
||
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", cchh.get("%NOC", nomenclatura, "S5"));
|
||
rc->put("NOMENCL", nomenclatura);
|
||
rc->put("PAESE", paese);
|
||
rc->put("PAESEORIG", paeseorig);
|
||
rc->put("PROV", provincia);
|
||
righe.add(key, rc);
|
||
}
|
||
const real qta = rr.quantita();
|
||
const real imp = rr.importo(TRUE, FALSE);
|
||
const real imp_val = imp * cambio;
|
||
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");
|
||
|
||
ammlire += is_val ? imp_val : imp;
|
||
ammvaluta += is_val ? imp : ZERO;
|
||
massakg += qta * rec_anamag.get_real(ANAMAG_MASSANUN);
|
||
massaums += qta * rec_anamag.get_real(ANAMAG_UNSUPPUN);
|
||
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);
|
||
|
||
totale_righe += is_val ? imp_val : imp;
|
||
}
|
||
}
|
||
|
||
// 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);
|
||
// 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", rm.get_real(MOV_TOTDOC));
|
||
intra.put("TOTDOCIMM", totale_righe);
|
||
intra.put("CODVAL", rm.get(MOV_CODVAL));
|
||
intra.put("CAMBIO", rm.get_real(MOV_CAMBIO));
|
||
if (intra.write() == _isdupkey) // Sebbene non debba succedere, si effettua una riscrittura
|
||
intra.rewrite();
|
||
|
||
// righe!
|
||
if (intra.status() != NOERR || rintra.write(TRUE) != NOERR) // Forza la riscrittura se necessario
|
||
_error = intra_mov_error;
|
||
|
||
return _error;
|
||
}
|
||
|
||
void TContabilizzazione::display_error(TDocumento& doc)
|
||
{
|
||
TString msg;
|
||
TString numerazione = doc.numerazione();
|
||
const long numero = doc.numero();
|
||
|
||
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 inserito.",(const char*)numerazione,numero);
|
||
break;
|
||
case counter_p_ant_error:
|
||
msg.format("Rilevato un errore cercando il conto di contropartita per il movimetno di anticipo relativamente al documento %s/%ld."
|
||
"Verificare l'esistenza la correttezza della causale specificata.",(const char*)numerazione,numero);
|
||
break;
|
||
case caus_error:
|
||
msg.format("Rilevato un errore caricando la causale relativamente al documento %s/%ld."
|
||
"Verificare l'esistenza del codice causale inserito.",(const char*)numerazione,numero);
|
||
break;
|
||
case cauval_error:
|
||
msg.format("Il documento %s/%ld risulta essere in valuta mentre la causale specificata non la supporta."
|
||
"Verificare la correttezza della causale inserita.",(const char*)numerazione,numero);
|
||
break;
|
||
case ivasto_error:
|
||
msg.format("Impossibile determinare il codice IVA di storno per articoli omaggio relativamente al documento %s/%ld."
|
||
"Verificare la configurazione contabilizzazione.",(const char*)numerazione,numero);
|
||
break;
|
||
case register_error:
|
||
msg.format("Rilevato un errore caricando il registro relativamente al documento %s/%ld."
|
||
"Verificare l'esistenza del codice causale/registro inseriti.",(const char*)numerazione,numero);
|
||
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."
|
||
"Verificare l'esistenza dei vari codici riga inseriti.",(const char*)numerazione,numero);
|
||
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 conto_error:
|
||
msg.format("Rilevato un conto di costo/ricavo inesistente relativamente al documento %s/%ld."
|
||
"Verificare l'esistenza dei conti associati alle righe.",(const char*)numerazione,numero);
|
||
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;
|
||
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;
|
||
}
|
||
warning_box(msg);
|
||
_error = no_error; // reset error, as any other one would do, so you can show me the other ones.
|
||
_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
|
||
{
|
||
bool rt = _sc_enabled;
|
||
if (_caus != NULL) rt &= _caus->saldaconto();
|
||
if (_clifo != NULL) rt &= !_clifo->lfile().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::elabora(TLista_documenti& doc_in, TLista_documenti& doc_out,
|
||
const TDate& data_elab, bool interattivo)
|
||
{
|
||
|
||
_error = no_error;
|
||
_can_write = TRUE;
|
||
_total_docs = 0L;
|
||
_caus = NULL;
|
||
_data_reg = data_elab;
|
||
_esc.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;
|
||
|
||
const int items = doc_in.items(); // Numero dei documenti in questa elaborazione
|
||
TProgind p(items,"Contabilizzazione documenti",FALSE,TRUE,1);
|
||
for (int i = 0; i < items ; i++) // Scorriamo tutti i documenti nella lista
|
||
{
|
||
p.setstatus(i+1);
|
||
TDocumento& doc = doc_in[i];
|
||
|
||
_movimento = new TMovimentoPN_VE(doc.in_valuta());
|
||
|
||
compile_head_mov(doc);
|
||
if (good())
|
||
compile_rows_mov(doc);
|
||
|
||
if (good() && _can_write)
|
||
if (write_all(doc) == no_error) // Se la scrittura e' andata ok...
|
||
{
|
||
if (doc.get_real(DOC_IMPPAGATO) != ZERO)
|
||
write_anticipo(doc);
|
||
|
||
if (good() && in_enabled())
|
||
write_intra(doc);
|
||
|
||
if (good())
|
||
{
|
||
_total_docs++;
|
||
change_doc_status(doc);
|
||
}
|
||
}
|
||
if (_caus != NULL)
|
||
{
|
||
delete _caus;
|
||
_caus = NULL;
|
||
}
|
||
if (!good())
|
||
display_error(doc);
|
||
delete _movimento;
|
||
}
|
||
|
||
return _can_write; // Se non ha riscontrato errori per nessun documento, _can_write = TRUE
|
||
}
|
||
|