821 lines
22 KiB
C++
Executable File
821 lines
22 KiB
C++
Executable File
#include "velib07.h"
|
||
|
||
#include "../cg/cgsaldac.h"
|
||
#include "../cg/cglib02.h"
|
||
#include "../db/dblib.h"
|
||
|
||
#include <pconti.h>
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TMateriali_base_recordset
|
||
///////////////////////////////////////////////////////////
|
||
|
||
const TVariant& TMateriali_base_recordset::get(const char* column_name) const
|
||
{
|
||
if (column_name[0] != '#')
|
||
{
|
||
TVariant& var = get_tmp_var();
|
||
int rownum = current_row();
|
||
|
||
if (reverse())
|
||
rownum = items() - 1 - rownum;
|
||
|
||
const TRiga_esplosione* row = (const TRiga_esplosione*)boom().objptr(rownum);
|
||
|
||
if (row != NULL)
|
||
{
|
||
const TFixed_string name(column_name);
|
||
if (name == "LASTQTA")
|
||
var = row->last_qta();
|
||
else
|
||
if (name == "TOTQTA")
|
||
var = row->val();
|
||
else
|
||
{
|
||
if (rownum != _lastrow)
|
||
{
|
||
((TMateriali_base_recordset *) this)->_lastrow = rownum;
|
||
const TCodice_articolo & comp = row->componente();
|
||
const TCodice_articolo & dist = row->distinta();
|
||
TLocalisamfile rd(LF_RDIST);
|
||
|
||
rd.setkey(2);
|
||
rd.put("CODCOMP", comp);
|
||
rd.put("CODDIST", dist);
|
||
if (rd.read() == NOERR)
|
||
*_rdist = rd.curr();
|
||
}
|
||
|
||
|
||
if (_rdist != NULL)
|
||
{
|
||
const TString & v = _rdist->get(column_name);
|
||
|
||
var = v;
|
||
}
|
||
}
|
||
}
|
||
return var;
|
||
}
|
||
return TRecordset::get(column_name);
|
||
}
|
||
|
||
const TVariant& TMateriali_base_recordset::get(unsigned int column) const
|
||
{
|
||
const TRecordset_column_info & ci = column_info(column);
|
||
return get(ci._name);
|
||
}
|
||
|
||
void TMateriali_base_recordset::requery()
|
||
{
|
||
_boom.destroy();
|
||
int pos1 = query_text().find("MATBASE");
|
||
if (pos1 > 0)
|
||
{
|
||
pos1 += 7;
|
||
set_reverse(query_text()[pos1] == '-');
|
||
if (reverse())
|
||
pos1++;
|
||
int pos = query_text().find("==", pos1);
|
||
int pos2 = -1;
|
||
if (pos > 0)
|
||
{
|
||
TString val(query_text().mid(pos + 2));
|
||
pos2 = val.find("FILTER");
|
||
|
||
if (pos2 > 0)
|
||
val.cut(pos2 - 1);
|
||
|
||
if (val.starts_with("\"") || val.starts_with("'"))
|
||
{
|
||
val.ltrim(1);
|
||
val.rtrim(1);
|
||
}
|
||
else
|
||
{
|
||
TVariant var = get(val);
|
||
val = var.as_string();
|
||
}
|
||
|
||
const TCodice_articolo art(val);
|
||
TDistinta_tree distinta;
|
||
if (distinta.set_root(art))
|
||
{
|
||
while (isspace(query_text()[pos1]))
|
||
pos1++;
|
||
const int level = atoi(query_text().mid(pos1));
|
||
if (level > 0 || query_text()[pos1] =='0')
|
||
while (isdigit(query_text()[pos1]))
|
||
pos1++;
|
||
while (isspace(query_text()[pos1]))
|
||
pos1++;
|
||
TString8 filter;
|
||
if (query_text()[pos1] != 'S')
|
||
while (isalpha(query_text()[pos1]))
|
||
filter << query_text()[pos1++];
|
||
distinta.explode(_boom, true, RAGGR_EXP_NONE, level, filter);
|
||
}
|
||
pos = query_text().find("FILTER", pos);
|
||
if (pos > 0)
|
||
{
|
||
pos = query_text().find("==", pos);
|
||
if (pos > 0)
|
||
{
|
||
TString val(query_text().mid(pos + 2));
|
||
|
||
if (val.starts_with("\"") || val.starts_with("'"))
|
||
{
|
||
val.ltrim(1);
|
||
val.rtrim(1);
|
||
}
|
||
else
|
||
{
|
||
TVariant var = get(val);
|
||
val = var.as_string();
|
||
}
|
||
const int items = _boom.items();
|
||
for (int i = 0; i < items; i++)
|
||
{
|
||
const TRiga_esplosione * row = (const TRiga_esplosione *)_boom.objptr(i);
|
||
if ( row != NULL && row->componente() != val)
|
||
_boom.destroy(i);
|
||
}
|
||
_boom.pack();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
TMateriali_base_recordset::TMateriali_base_recordset(const char* use) : _query(use)
|
||
{
|
||
_lastrow = -1;
|
||
_rdist = new TRectype(LF_RDIST);
|
||
const int nfields = _rdist->items();
|
||
|
||
int pos = 1;
|
||
for ( int i = 0 ; i < nfields; i++)
|
||
{
|
||
TRecordset_column_info * ci = new TRecordset_column_info;
|
||
|
||
ci->_name = _rdist->fieldname(i);
|
||
ci->_pos = pos;
|
||
ci->_type = _rdist->type(ci->_name);
|
||
|
||
const int len = _rdist->length(ci->_name);
|
||
|
||
pos += len;
|
||
ci->_width = len;
|
||
_column.add(ci);
|
||
}
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TScalare_recordset
|
||
///////////////////////////////////////////////////////////
|
||
|
||
void TScalare_recordset::requery()
|
||
{
|
||
boom().destroy();
|
||
int pos1 = query_text().find("SCALARE");
|
||
if (pos1 > 0)
|
||
{
|
||
pos1 += 7;
|
||
set_reverse(query_text()[pos1] == '-');
|
||
if (reverse())
|
||
pos1++;
|
||
int pos = query_text().find("==", pos1);
|
||
if (pos > 0)
|
||
{
|
||
TString val(query_text().mid(pos + 2));
|
||
|
||
if (val.starts_with("\"") || val.starts_with("'"))
|
||
{
|
||
val.ltrim(1);
|
||
val.rtrim(1);
|
||
}
|
||
else
|
||
{
|
||
TVariant var = get(val);
|
||
val = var.as_string();
|
||
}
|
||
|
||
const TCodice_articolo art(val);
|
||
TDistinta_tree distinta;
|
||
if (distinta.set_root(art))
|
||
{
|
||
while (isspace(query_text()[pos1]))
|
||
pos1++;
|
||
const int level = atoi(query_text().mid(pos1));
|
||
if (level > 0 || query_text()[pos1] =='0')
|
||
while (isdigit(query_text()[pos1]))
|
||
pos1++;
|
||
while (isspace(query_text()[pos1]))
|
||
pos1++;
|
||
TString8 filter;
|
||
if (query_text()[pos1] != 'S')
|
||
while (isalpha(query_text()[pos1]))
|
||
filter << query_text()[pos1++];
|
||
distinta.explode(boom(), false, RAGGR_EXP_NONE, level, filter);
|
||
}
|
||
pos = query_text().find("FILTER", pos);
|
||
if (pos > 0)
|
||
{
|
||
pos = query_text().find("==", pos);
|
||
if (pos > 0)
|
||
{
|
||
TString val(query_text().mid(pos + 2));
|
||
|
||
if (val.starts_with("\"") || val.starts_with("'"))
|
||
{
|
||
val.ltrim(1);
|
||
val.rtrim(1);
|
||
}
|
||
else
|
||
{
|
||
TVariant var = get(val);
|
||
val = var.as_string();
|
||
}
|
||
const int items = boom().items();
|
||
for (int i = 0; i < items; i++)
|
||
{
|
||
const TRiga_esplosione * row = (const TRiga_esplosione *)boom().objptr(i);
|
||
if ( row != NULL && row->componente() != val)
|
||
boom().destroy(i);
|
||
}
|
||
boom().pack();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TDocument_cache
|
||
///////////////////////////////////////////////////////////
|
||
TObject* TDocument_cache::key2obj(const char* key)
|
||
{
|
||
TToken_string k(key);
|
||
const char provv = *k.get(0);
|
||
const int anno = k.get_int();
|
||
const TString4 codnum= k.get();
|
||
const long ndoc = k.get_long();
|
||
TDocumento* doc = new TDocumento(provv, anno, codnum, ndoc);
|
||
doc->get("IMPONIBILI"); // Bastardata per far funzionare la successiva dirty_fields
|
||
doc->dirty_fields();
|
||
return doc;
|
||
}
|
||
|
||
TDocumento& TDocument_cache::doc(const TRectype& rec)
|
||
{
|
||
TToken_string key;
|
||
key = rec.get(DOC_PROVV);
|
||
key.add(rec.get(DOC_ANNO));
|
||
key.add(rec.get(DOC_CODNUM));
|
||
key.add(rec.get(DOC_NDOC));
|
||
TDocumento& d = *(TDocumento*)objptr(key);
|
||
return d;
|
||
}
|
||
|
||
|
||
TDocument_cache:: TDocument_cache() : TCache(3)
|
||
{
|
||
}
|
||
|
||
TDocument_cache:: ~TDocument_cache()
|
||
{
|
||
}
|
||
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TDocument_recordset
|
||
///////////////////////////////////////////////////////////
|
||
|
||
const TVariant& TDocument_recordset::get_field(int num, const char* field) const
|
||
{
|
||
if (*field != '#')
|
||
{
|
||
const int idx = relation()->log2ind(num);
|
||
if (idx < 0)
|
||
return NULL_VARIANT;
|
||
const int logic = num > 0 ? num : relation()->file(idx).num();
|
||
if (logic == LF_DOC || logic == LF_RIGHEDOC)
|
||
{
|
||
const TRectype& rec = relation()->file(idx).curr();
|
||
// Se non e' un campo standard, ma e' calcolato da una formula...
|
||
if (rec.type(field) == _nullfld && strncmp(field, "G1:", 3) != 0)
|
||
{
|
||
const TDocumento& doc = ((TDocument_cache&)_cache).doc(rec);
|
||
TVariant& var = get_tmp_var();
|
||
|
||
if (xvt_str_compare_ignoring_case(field, "SEGNO") == 0)
|
||
{
|
||
var = doc.is_nota_credito() ? -UNO : UNO;
|
||
} else
|
||
if (xvt_str_compare_ignoring_case(field, "IS_COSTO") == 0)
|
||
{
|
||
bool costo = (doc.tipo().is_costo()) || (!doc.tipo().is_ricavo() && doc.get_char(DOC_TIPOCF)=='F');
|
||
var = costo ? UNO : ZERO;
|
||
} else
|
||
if (xvt_str_compare_ignoring_case(field, "IS_RICAVO") == 0)
|
||
{
|
||
bool ricavo = (doc.tipo().is_ricavo()) || (!doc.tipo().is_costo() && doc.get_char(DOC_TIPOCF)=='C');
|
||
var = ricavo ? UNO : ZERO;
|
||
}
|
||
else
|
||
{
|
||
const TFieldref ref(field, logic);
|
||
if (logic == LF_DOC)
|
||
{
|
||
var = ref.read(doc);
|
||
}
|
||
else
|
||
{
|
||
const int nriga = rec.get_int(RDOC_NRIGA);
|
||
if (nriga > 0 && nriga <= doc.rows())
|
||
{
|
||
const TRiga_documento& rdoc = doc[nriga];
|
||
var = ref.read(rdoc);
|
||
}
|
||
else
|
||
var = NULL_VARIANT;
|
||
}
|
||
}
|
||
return var;
|
||
}
|
||
}
|
||
}
|
||
return TISAM_recordset::get_field(num, field);
|
||
}
|
||
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// TDocument_report
|
||
///////////////////////////////////////////////////////////
|
||
|
||
bool TDocument_report::set_recordset(const TString& query)
|
||
{
|
||
if (query.find("MATBASE") > 0)
|
||
return TReport::set_recordset(new TMateriali_base_recordset(query));
|
||
if (query.find("SCALARE") > 0)
|
||
return TReport::set_recordset(new TScalare_recordset(query));
|
||
|
||
return TReport::set_recordset(new TDocument_recordset(query));
|
||
}
|
||
|
||
bool TDocument_report::load(const char* name)
|
||
{
|
||
const bool ok = TReport::load(name);
|
||
if (ok)
|
||
{
|
||
// Purtroppo il recordset delle sottosezioni deve essere reimpostato a mano
|
||
for (int i = 11; i <= 999; i++)
|
||
{
|
||
TReport_section* sec = find_section('B', i);
|
||
if (sec != NULL)
|
||
{
|
||
TRecordset* recset = sec->recordset();
|
||
if (recset != NULL)
|
||
{
|
||
const TString use = recset->query_text();
|
||
if (use.find("MATBASE") > 0)
|
||
recset = new TMateriali_base_recordset(use);
|
||
else
|
||
if (use.find("SCALARE") > 0)
|
||
recset = new TScalare_recordset(use);
|
||
else
|
||
recset = new TDocument_recordset(use);
|
||
sec->set_recordset(recset);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
void TDocument_report::output_values(const TRectype& rec, const TString& output)
|
||
{
|
||
TToken_string out(output, '!');
|
||
TString curr;
|
||
for (const char * str = out.get(0); str; str = out.get())
|
||
{ // scansione sugli elementi dell'output
|
||
curr = str;
|
||
int poseq = curr.find('='); // divide la stringa corrente in lvalue e rvalue
|
||
if (poseq < 0)
|
||
{
|
||
curr_field()->set(rec.get(curr));
|
||
}
|
||
else
|
||
{
|
||
int posrv = poseq+1;
|
||
if (poseq >= 0 && curr[posrv] == '=')
|
||
posrv++;
|
||
TString16 fld(curr.left(poseq)); // preleva il nome del campo del form alla sinistra dell'uguale
|
||
const TString& dat = rec.get(curr.mid(posrv)); // preleva il nome del campo del file alla destra dell'uguale e lo legge dal record
|
||
TReport_field* campo = field(fld);
|
||
if (campo != NULL)
|
||
campo->set(dat);
|
||
}
|
||
}
|
||
}
|
||
|
||
void TDocument_report::reset_values(const TString& output)
|
||
{
|
||
TToken_string out(output, '!');
|
||
TString curr;
|
||
for (const char * str = out.get(0); str; str = out.get())
|
||
{ // scansione sugli elementi dell'output
|
||
curr = str;
|
||
int poseq = curr.find('='); // divide la stringa corrente in lvalue e rvalue
|
||
if (poseq < 0)
|
||
{
|
||
curr_field()->set("");
|
||
}
|
||
else
|
||
{
|
||
TString16 fld(curr.left(poseq)); // preleva il nome del campo del form alla sinistra dell'uguale
|
||
TReport_field* campo = field(fld);
|
||
if (campo != NULL)
|
||
campo->set("");
|
||
}
|
||
}
|
||
}
|
||
|
||
bool TDocument_report::msg_parent_doc(TVariant_stack& stack)
|
||
{
|
||
TReport_field& cf = *curr_field();
|
||
|
||
int idx =((TISAM_recordset *)recordset())->cursor()->relation()->log2ind(LF_DOC);
|
||
|
||
if (idx < 0)
|
||
return false;
|
||
|
||
const TRectype& rec = ((TISAM_recordset*)recordset())->cursor()->relation()->file(idx).curr();
|
||
TDocumento & doc = (TDocumento &)((TDocument_recordset*)recordset())->doc(rec);
|
||
const TRiga_documento * rdoc = NULL;
|
||
|
||
// Se il campo corrente non appartiene al body allora cerco la prima riga documento buona!
|
||
if (cf.section().type() == 'B')
|
||
{
|
||
idx = ((TISAM_recordset*)recordset())->cursor()->relation()->log2ind(LF_RIGHEDOC);
|
||
if (idx < 0)
|
||
return false;
|
||
|
||
const TRectype& rec = ((TISAM_recordset*)recordset())->cursor()->relation()->file(idx).curr();
|
||
const int n = rec.get_long("NRIGA");
|
||
|
||
rdoc = &(doc[n]);
|
||
}
|
||
else
|
||
{
|
||
const TRiga_documento * first_desc = NULL;
|
||
|
||
for (int r = 1; r <= doc.physical_rows(); r++)
|
||
{
|
||
const TRiga_documento& row = doc[r];
|
||
if (row.get(RDOC_DANDOC).not_empty())
|
||
{
|
||
if (row.is_descrizione())
|
||
{
|
||
if (first_desc == NULL)
|
||
first_desc = &row; // Non e' una riga buona, ma nemmeno da buttare!
|
||
}
|
||
else
|
||
{
|
||
rdoc = &row;
|
||
break; // Ho trovato la riga buona!
|
||
}
|
||
}
|
||
}
|
||
if (rdoc == NULL && first_desc != NULL)
|
||
rdoc = first_desc;
|
||
}
|
||
|
||
int level = stack.pop().as_int();
|
||
for (; rdoc != NULL && level > 0; level--)
|
||
rdoc = (const TRiga_documento*)(rdoc->find_original_rdoc());
|
||
|
||
const TString& values = stack.pop().as_string();
|
||
const bool is_full = stack.peek().as_bool();
|
||
|
||
if (rdoc != NULL && rdoc->get(RDOC_PROVV).not_empty())
|
||
{
|
||
const char provv = rdoc->get_char(RDOC_PROVV);
|
||
const int anno = rdoc->get_int(RDOC_ANNO);
|
||
const TString4 codnum = rdoc->get(RDOC_CODNUM);
|
||
const long ndoc = rdoc->get_long(RDOC_NDOC);
|
||
|
||
if (is_full)
|
||
{
|
||
TDocumento doc(provv, anno, codnum, ndoc);
|
||
output_values(doc, values);
|
||
}
|
||
else
|
||
{
|
||
TToken_string key;
|
||
key.add(provv); key.add(anno); key.add(codnum); key.add(ndoc);
|
||
const TRectype& doc = cache().get(LF_DOC, key);
|
||
output_values(doc, values);
|
||
}
|
||
}
|
||
else
|
||
reset_values(values);
|
||
|
||
return true;
|
||
}
|
||
|
||
bool TDocument_report::msg_parent_row(TVariant_stack& stack)
|
||
{
|
||
int idx = ((TISAM_recordset*)recordset())->cursor()->relation()->log2ind(LF_RIGHEDOC);
|
||
if (idx < 0)
|
||
return false;
|
||
|
||
const TRectype& rec = ((TISAM_recordset*)recordset())->cursor()->relation()->file(idx).curr();
|
||
const int n = rec.get_long("NRIGA");
|
||
idx =((TISAM_recordset *)recordset())->cursor()->relation()->log2ind(LF_DOC);
|
||
|
||
if (idx < 0)
|
||
return false;
|
||
|
||
TDocumento & doc = (TDocumento &)((TDocument_recordset*)recordset())->doc(rec);
|
||
|
||
const TRiga_documento * rdoc = &(doc[n]);
|
||
|
||
// Se il campo corrente non appartiene al body allora cerco la prima riga documento buona!
|
||
|
||
int level = stack.pop().as_int();
|
||
for (; rdoc != NULL && level > 0; level--)
|
||
rdoc = (const TRiga_documento *)(rdoc->find_original_rdoc());
|
||
|
||
const TString& values = stack.pop().as_string();
|
||
const bool is_full = stack.peek().as_bool();
|
||
|
||
if (rdoc != NULL && rdoc->get(RDOC_PROVV).not_empty())
|
||
{
|
||
if (is_full)
|
||
{
|
||
const char provv = rdoc->get_char(RDOC_PROVV);
|
||
const int anno = rdoc->get_int(RDOC_ANNO);
|
||
const TString4 codnum = rdoc->get(RDOC_CODNUM);
|
||
const long ndoc = rdoc->get_long(RDOC_NDOC);
|
||
TDocumento doc(provv, anno, codnum, ndoc);
|
||
output_values(doc[rdoc->get_int(RDOC_NRIGA)], values);
|
||
}
|
||
else
|
||
output_values(*rdoc, values);
|
||
}
|
||
return true;
|
||
}
|
||
|
||
size_t TDocument_report::get_usr_words(TString_array& words) const
|
||
{
|
||
TReport::get_usr_words(words);
|
||
|
||
const char* const name[] = { "DOC_PARENT_DOC", "DOC_PARENT_ROW", NULL };
|
||
|
||
((TDocument_report*)this)->_first_msg = words.items(); // Calcola il primo numero disponibile
|
||
for (size_t i = 0; name[i] != NULL; i++)
|
||
words.add(name[i]);
|
||
|
||
return words.items();
|
||
}
|
||
|
||
bool TDocument_report::execute_usr_word(unsigned int opcode, TVariant_stack& stack)
|
||
{
|
||
if (opcode < _first_msg)
|
||
return TReport::execute_usr_word(opcode, stack);
|
||
opcode -= _first_msg;
|
||
switch (opcode)
|
||
{
|
||
case 0 : msg_parent_doc(stack); break;
|
||
case 1 : msg_parent_row(stack); break;
|
||
default: break;
|
||
}
|
||
|
||
while (!stack.pop().is_null()); // Svuota eventuali parametri variabili inutilizzati
|
||
|
||
return true;
|
||
}
|
||
|
||
/////////////////////////////////////////
|
||
// Metodi non appartenenti a classi
|
||
/////////////////////////////////////////
|
||
|
||
// METODI PER IL CALCOLO DEL FIDO
|
||
|
||
//estrazioni mastri clienti e/o fornitori
|
||
static const TString_array& mastro(char tipocf)
|
||
{
|
||
static TString_array m[2];
|
||
const TString_array& a = m[tipocf == 'C' ? 0 : 1];
|
||
|
||
if (a.empty())
|
||
{
|
||
TISAM_recordset mastri("USE PCON SELECT (CONTO!=\"\")&&(SOTTOCONTO=\"\")");
|
||
for (bool ok = mastri.move_first(); ok; ok = mastri.move_next())
|
||
{
|
||
const int gruppo = mastri.get(PCN_GRUPPO).as_int();
|
||
const int conto = mastri.get(PCN_CONTO).as_int();
|
||
const int indbil = mastri.get(PCN_INDBIL).as_int();
|
||
const char tipocf = mastri.get(PCN_TMCF).as_string()[0];
|
||
TToken_string info;
|
||
info.add(gruppo);
|
||
info.add(conto);
|
||
info.add(indbil);
|
||
m[tipocf == 'C' ? 0 : 1].add(info);
|
||
}
|
||
}
|
||
return a;
|
||
}
|
||
|
||
static real calcola_saldo_contabile(const long codcf, const TDate& datacalc)
|
||
{
|
||
real saldone;
|
||
|
||
TEsercizi_contabili esc;
|
||
TDate datainies, datafines;
|
||
const int codes = esc.date2esc(datacalc);
|
||
if (codes > 0)
|
||
esc.code2range(codes, datainies, datafines);
|
||
else
|
||
{
|
||
datainies = datacalc;
|
||
datainies.set_day(1);
|
||
datainies.set_month(1);
|
||
}
|
||
|
||
const TString_array& a = mastro('C');
|
||
|
||
//per tutti i mastri selezionati va a calcolare il saldo del cliente/fornitore in input
|
||
FOR_EACH_ARRAY_ROW(a, i, row)
|
||
{
|
||
const int gruppo = row->get_int(0);
|
||
const int conto = row->get_int(1);
|
||
const int indbil = row->get_int(2);
|
||
|
||
TSaldo saldo;
|
||
real saldo_periodo = saldo.saldo_periodo(gruppo, conto, codcf, datainies, datacalc, indbil, false);
|
||
|
||
saldone += saldo_periodo;
|
||
}
|
||
return saldone;
|
||
}
|
||
|
||
static TImporto get_importo(const TISAM_recordset& partite, const char* sezione, const char* valore)
|
||
{
|
||
const char sez = partite.get(sezione).as_string()[0];
|
||
const real val = partite.get(valore).as_real();
|
||
return TImporto(sez, val);
|
||
}
|
||
|
||
|
||
static real calcola_esposto_da_saldaconto (long codcf, const TDate& datacalc)
|
||
{
|
||
const int riskdays = ini_get_int(CONFIG_DITTA, "ve", "FIDO_RISKDAYS");
|
||
|
||
//estrae le righe partita relative a pagamenti successivi alla data di rischio (e con tipopag >2,<7)
|
||
TString query;
|
||
query << "USE PART\nSELECT BETWEEN(DATAPAG,#DATASBF,0)&&BETWEEN(TIPOPAG,2,7)\n";
|
||
query << "FROM TIPOC=C GRUPPO=0 CONTO=0 SOTTOCONTO=#CODCF ANNO=#ANNO\n";
|
||
query << "TO TIPOC=C GRUPPO=0 CONTO=0 SOTTOCONTO=#CODCF";
|
||
|
||
TISAM_recordset partite(query);
|
||
|
||
partite.set_var("#CODCF", codcf);
|
||
partite.set_var("#DATACALC", datacalc);
|
||
//data considerante i giorni di rischio ammessi dall'utonto
|
||
TDate data_sbf = datacalc;
|
||
data_sbf -= riskdays;
|
||
partite.set_var("#DATASBF", data_sbf); //data salvo buon fine
|
||
partite.set_var("#ANNO", TVariant((long)data_sbf.year()));
|
||
|
||
|
||
//importone somma degli importi delle righe del recordset
|
||
TImporto importone_esposto;
|
||
|
||
for (bool ok = partite.move_first(); ok; ok = partite.move_next())
|
||
{
|
||
TImporto importo_riga;
|
||
|
||
//fatture,note di credito,pagamenti
|
||
TImporto importo_partita = get_importo(partite, PART_SEZ, PART_IMPORTO);
|
||
importo_riga += importo_partita;
|
||
|
||
//pagamenti (tm=3), insoluti (tm=5), pagamenti insoluti(tm=6)
|
||
if (partite.get(PART_TIPOMOV).as_int() >= tm_pagamento)
|
||
{
|
||
TImporto importo_abbuono = get_importo(partite, PART_SEZABB, PART_ABBUONI);
|
||
importo_riga += importo_abbuono;
|
||
//pagamenti in valuta
|
||
if (!partite.get(PART_CODVAL).is_empty())
|
||
{
|
||
TImporto importo_diff_cambio = get_importo(partite, PART_SEZDIFCAM, PART_DIFFCAM);
|
||
importo_riga += importo_diff_cambio;
|
||
}
|
||
}
|
||
|
||
//somma importi presenti sulla riga partita (fatture, pagamenti, insoluti, pagamenti insoluti)
|
||
importone_esposto += importo_riga;
|
||
|
||
}
|
||
//la normalizzazione del totale delle partite va fatta in base al fatto che si parli di 'C'liente o 'F'ornitore
|
||
//const char sezione_finale = (tipocf == 'C') ? 'A' : 'D';
|
||
importone_esposto.normalize('A');
|
||
|
||
//valore in output
|
||
real esposto;
|
||
esposto += importone_esposto.valore();
|
||
|
||
return esposto;
|
||
}
|
||
|
||
|
||
static real calcola_fido_da_documenti(long codcf, const TDate& datacalc, const TDoc_key& ignore)
|
||
{
|
||
real totalone;
|
||
|
||
// scansione delle righe FIDO_XX(j)=.. sul paragrafo di configurazione VE
|
||
// per avere i parametri di numerazione/tipo da considerare
|
||
TConfig config(CONFIG_DITTA, "ve");
|
||
for (int j = 0; ;j++)
|
||
{
|
||
const TString& num_fido = config.get("FIDO_NUM", NULL, j);
|
||
//se manca la numerazione si pu<70> fermare,in quanto non pu<70> esistere un tipo senza numerazione
|
||
if (num_fido.blank())
|
||
break;
|
||
const TString& tipo_fido = config.get("FIDO_TIP", NULL, j);
|
||
const TString& da_stato_fido = config.get("FIDO_DASTA", NULL, j);
|
||
const TString& a_stato_fido = config.get("FIDO_ASTA", NULL, j);
|
||
const bool residuo_fido = config.get_bool("FIDO_RES", NULL, j);
|
||
|
||
//per la numerazione scelta queryzza gli archivi alla ricerca dei documenti che rientrano nei parametri
|
||
TString query;
|
||
query << "USE DOC KEY 2\n";
|
||
query << "SELECT (CODNUM=#CODNUM)&&(TIPODOC=#TIPODOC)&&(BETWEEN(STATO,#DASTATO,#ASTATO))\n";
|
||
query << "FROM TIPOCF=C CODCF=#CODCF PROVV='D'\n";
|
||
query << "TO TIPOCF=C CODCF=#CODCF PROVV='D' ANNO=#ANNO DATADOC=#DATACALC";
|
||
|
||
TISAM_recordset documenti(query);
|
||
|
||
documenti.set_var("#CODCF", codcf);
|
||
documenti.set_var("#ANNO", (long)datacalc.year());
|
||
documenti.set_var("#DATACALC", datacalc);
|
||
documenti.set_var("#CODNUM", num_fido);
|
||
documenti.set_var("#TIPODOC", tipo_fido);
|
||
documenti.set_var("#DASTATO", da_stato_fido);
|
||
documenti.set_var("#ASTATO", a_stato_fido);
|
||
|
||
const int items = documenti.items();
|
||
if (items > 0)
|
||
{
|
||
const TRectype& curr = documenti.cursor()->curr();
|
||
//adesso che ha i documenti che cercava..
|
||
for (bool ok = documenti.move_first(); ok; ok = documenti.move_next())
|
||
{
|
||
if (ignore.full())
|
||
{
|
||
const TDoc_key k(curr);
|
||
if (k == ignore)
|
||
continue;
|
||
}
|
||
|
||
const TDocumento doc(curr);
|
||
//deve tener conto di eventuali docs in valuta
|
||
TCurrency_documento totdoc(ZERO, doc);
|
||
|
||
//documento a residuo (tipo ordini)
|
||
if (residuo_fido)
|
||
totdoc.set_num(doc.valore(false, true));
|
||
else //documento normale (tipo fattura)
|
||
totdoc.set_num(doc.totale_doc());
|
||
|
||
totdoc.change_to_firm_val();
|
||
|
||
//le nac vanno con segno rovesciato
|
||
if (doc.is_nota_credito())
|
||
totdoc = -totdoc;
|
||
|
||
totalone += totdoc.get_num();
|
||
}
|
||
}
|
||
}
|
||
|
||
return totalone;
|
||
}
|
||
|
||
|
||
//metodo per il calcolo fido di un cliente ad una data definita
|
||
real calcola_fido_cliente (long codcf, const TDate& datacalc, const TDoc_key& ignore)
|
||
{
|
||
//PRIMA PARTE: controlla i movimenti
|
||
real saldo_contabile = calcola_saldo_contabile(codcf, datacalc);
|
||
//SECONDA PARTE: controlla il saldaconto
|
||
real esposto_saldaconto = calcola_esposto_da_saldaconto(codcf, datacalc);
|
||
//TERZA PARTE: controlla i documenti
|
||
real tot_documenti = calcola_fido_da_documenti(codcf, datacalc, ignore);
|
||
|
||
return saldo_contabile + esposto_saldaconto + tot_documenti;
|
||
}
|
||
|
||
// FINE METODI PER IL CALCOLO DEL FIDO
|