campo-sirio/src/ve/velib03a.cpp
bonazzi 4340c62336 Patch level : 12.0 428
Files correlati     : ve0.exe ve0300a.ini ve0100a.msk ve0200g.msk ve1300.alx ve1.exe ve17001.rep ve17002.rep ve1700a.msk ve1700a.msk ve6.exe ve61000a.msk ve17001.rep ve17002.rep ve17002.rep ve17001.rep ve1700a.msk vemenu.men

Corretta l'impostazione del flag split payment nella contabilizzazione fatture.
Gestita la concorrenza nell'attribuzione del protocollo IVA sempre in contabilizzazione

MODIFICHE CRPA

Se si mette il flag P sulla data documento della maschera di un tipo documento viene proposta l’ultima data inserita.
 - il flag P deve essere messo nei flag del campo data documento della maschera del tipo documento
 
Possibilità di impostare il numero di copie da stampare nel menu Opzioni-> Copie nell’inserimento/modifica di un documento.

Copia righe documento.
 - Nel menu contestuale dello sheet dei documenti (tasto destro ci sono 4 nuovi item :
     Seleziona (seleziona la riga corrente come inizio o fine selezione)
     Azzera selezione
     Copia (copia le righe selezionate)
      Incolla (incolla le righe copiate)

Righe documento massime 10000.
 - Per testarlo bisogna trovare un documento con più di 999 righe.

Aggiunta ricerca per riferimento cliente (ricerca alternativa).
 - Per testarlo bisogna rigenerare il profilio standard non lo farei ora, e il capo non c'è non deve dare errori.

Aggiunto indirizzo cliente/fornitore sulla ricerca documenti.

Lista documenti avanzata (report).
 - Nuovo item di menu in Documenti->Servizi->Stampa avanzata riepilogo documenti immessi.

Aggiunte le regolarizzazioni nella contabilizzazione documenti.
 - Se la causale prevede le regolarizzazione e il fonitore ha il codice cliente associato deve fare anche il movimento di regolarizzazione.

Sistemata abilitazione della data registrazione in contabilizzazione documenti

Aggiunta la possibilità di usare campi del documento nella dicitura del riferimento.
 - Nella tabella tipo documento nel campo riferimento si possono usare campi della testata documento tra parentesi graffa (es. {TIPODOC}) oltre che campi dei clienti/fornitori
   (es. {CLIFO.RICALT}

Gestiti i movimenti di sola iva in contabilizzazione.
 - in relazione coi movimenti di regolarizzazione, se la causale è di sola IVA deve contabilizzare il documento.

Riferimento per mese nelle partite.
 - gestito il riferimento partita per mese come da configurazione contabile nella contabilizzazione.

Ordinamento per documento nell’evasione ordini con un flag in configurazione
 - ordina per codice articolo  le righe se impostato il campo ordina per codice nella tabella elaborazioni differite

Impostato il tipo CF in base al tipo documento
 -Deve impostare corrattamente il tipo cliente fornitore in relazione al tipo documento.
 
Aggiunto il messaggio cliente alla stampa report delle vendite
 - E' utilizzato nei report standard della lista documenti avanzata se quella funziona funziona anche questo.



git-svn-id: svn://10.65.10.50/branches/R_10_00@24044 c028cbd2-c16b-5b4b-a496-9718f37d4682
2017-08-23 08:32:19 +00:00

1226 lines
30 KiB
C++
Executable File

#include "velib.h"
#include "vepriv.h"
#include "verig.h"
#include <tabutil.h>
#include <utility.h>
#include "../db/dblib.h"
#include "../mg/mglib.h"
///////////////// //////////////////////////////////////////
// Tipo documento
///////////////////////////////////////////////////////////
TAssoc_array TTipo_documento::_formule_documento;
TTipo_documento::TTipo_documento(const char* tipodoc)
: TRectype(LF_TABCOM), _tipocf('\0')
{
settab("TIP");
if (tipodoc && *tipodoc)
read(tipodoc);
}
TTipo_documento::TTipo_documento(const TRectype& rec)
: TRectype(rec), _tipocf('\0')
{ read_formule(); }
TTipo_documento::~TTipo_documento()
{ }
int TTipo_documento::read(const char* tipodoc)
{
*this = cache().get("%TIP", tipodoc);
int err = empty() ? _iskeynotfound : NOERR;
_formule.cut(0);
if (err == NOERR)
read_formule();
else
yesnofatal_box("Tipo documento errato: %s", tipodoc);
return err;
}
const TString& TTipo_documento::mask_name() const
{
TString& name = get_tmp_string();
name = get("S4");
name.cut(8);
name.trim();
return name;
}
const TFilename& TTipo_documento::profile_name(TFilename& profile) const
{
profile = get("S4");
profile.cut(8);
profile.trim();
profile.ext("ini");
return profile;
}
bool TTipo_documento::main_print_profile(TFilename& report, int filter) const
{
TString8 base = get("S5").left(8);
base.trim();
bool ok = base.full();
if (ok)
{
ok = false;
if (filter != 1)
{
report = base;
report.ext("rep");
ok = report.custom_path();
}
if (!ok && filter != 2)
{
report = base;
report.ext("frm");
ok = report.custom_path();
}
}
return ok;
}
bool TTipo_documento::additional_print_profile(TFilename& report, int filter) const
{
TString8 base = get("S5").mid(8, 8);
base.trim();
bool ok = base.full();
if (ok)
{
ok = false;
if (filter != 1) // Non voglio i soli frm
{
report = base;
report.ext("rep");
ok = report.custom_path();
}
if (!ok && filter != 2) // Non voglio i soli rep
{
report = base;
report.ext("frm");
ok = report.custom_path();
}
}
return ok;
}
bool TTipo_documento::mail_print_profile(TFilename& report) const
{
report = get("S5").mid(16, 8);
bool ok = report.full();
if (ok)
{
report.trim();
report.ext("rep");
ok = report.custom_path();
}
if (!ok)
ok = main_print_profile(report, 2); // Solo rep
return ok;
}
bool TTipo_documento::is_costo() const
{ return _tipocr == 'C' || tipocf() == 'F'; }
bool TTipo_documento::is_ricavo() const
{ return _tipocr == 'R' || tipocf() == 'C'; }
const char TTipo_documento::tipocf() const
{
if (_tipocf < ' ')
{
TFilename pn; profile_name(pn);
//(char&)_tipocf = ini_get_string(pn, "MAIN", "TIPOCF", "C")[0]; // NON FUNZIONA: ritorna sempre 'C'
TConfig ini(pn, "MAIN");
(char&)_tipocf = ini.get("TIPOCF", NULL, -1, "C")[0];
}
return _tipocf;
}
const TString& TTipo_documento::riferimento(const TDocumento & doc, TString& rif) const
{
rif = esc(get("S1"));
int p = rif.find('{');
bool ok = true;
while (p >= 0)
{
char conn = ' ';
int q = p + 1;
if (rif[q] == '\\' || rif[q] == '&' || rif[q] == '|')
conn = rif[q++];
const int last = rif.find('}');
const TString16 field_name(rif.sub(q, last));
const TFieldref field(field_name, LF_DOC);
if (last < 0)
rif.cut(p);
else
{
const int len = rif.len() - last;
for (int i = 0; i <= len; i++)
rif[p + i] = rif[last + i + 1];
}
TString val;
switch (field.file())
{
case LF_DOC:
val = field.read(doc);
break;
case LF_CLIFO:
case LF_CFVEN:
if (doc.get_long(DOC_CODCF) > 0)
{
TString8 key; key << doc.get(DOC_TIPOCF) << '|' << doc.get(DOC_CODCF);
const TRectype& rec = cache().get(field.file(), key);
val = field.read(rec);
}
break;
case LF_OCCAS:
if (doc.get_char(DOC_TIPOCF) == 'C' && doc.get(DOC_OCFPI).full())
{
const TRectype& rec = cache().get(LF_OCCAS, doc.get(DOC_OCFPI));
val = field.read(rec);
}
break;
default:
val = field.read(doc);
break;
}
rif.insert(val, p);
switch (conn)
{
case '\\' :
ok = val.full();
break;
case '&' :
ok &= val.full();
break;
case '|' :
ok |= val.full();
break;
default :
break;
}
p = rif.find('{');
}
if (!ok)
rif.cut(0);
return rif;
}
const TString_array& TTipo_documento::keys_descrs() const
{
if (_keys_descrs.empty())
{
TFilename name; profile_name(name);
TConfig prof(name, "RIGHE");
TTipo_riga_documento tr;
TToken_string k, d;
for (int i = 0; ; i++)
{
const TString& tiporiga = prof.get("Tipo", NULL, i);
if (tiporiga.full())
{
if (tr.read(tiporiga) == NOERR)
{
k.add(tr.codice());
d.add(tr.descrizione());
}
}
else
break; //esce da un eventuale ciclo infinito
}
if (k.blank())
{
TISAM_recordset tri("USE %TRI");
for (bool ok = tri.move_first(); ok; ok = tri.move_next())
{
name.format("verig%s.msk", (const char*)tri.get("CODTAB").as_string());
if (name.custom_path())
{
k.add(tri.get("CODTAB").as_string());
d.add(tri.get("S0").as_string());
}
}
}
// Fool const
((TString_array&)_keys_descrs).add(k);
((TString_array&)_keys_descrs).add(d);
}
return _keys_descrs;
}
const TString_array& TTipo_documento::sheet_columns() const
{
if (_sheet_columns.empty())
{
TFilename pn; profile_name(pn);
TConfig prof(pn, "SHEET");
for (int i = 0; i < MAX_COLUMNS; i++)
{
const TString& id = prof.get("Col", NULL, i);
if (atoi(id) <= 0)
break;
((TString_array&)_sheet_columns).add(id);
}
}
return _sheet_columns;
}
const TPointer_array& TTipo_documento::handlers() const
{
if (_handlers.empty())
{
TFilename pn; profile_name(pn);
TConfig prof(pn, "HANDLERS");
TAssoc_array& v = prof.list_variables();
TToken_string pair;
FOR_EACH_ASSOC_STRING(v, h, k, s)
{
int id = 0, hnd = 0;
pair = s;
switch (pair.items())
{
case 1:
{
const TFixed_string key(k);
id = atoi(key.after('('));
hnd = atoi(pair);
}
break;
case 2:
id = pair.get_int(0);
hnd = pair.get_int();
break;
default: break;
}
if (id > 10 && id < 1000 && hnd > 0)
((TPointer_array&)_handlers).add_long(hnd, id);
}
}
return _handlers;
}
const TString_array& TTipo_documento::get_defaults() const
{
if (_defaults.empty()) // Carica lo string_array con i defaults
{
TFilename pn; profile_name(pn);
TConfig prof(pn, "DEFAULT");
TToken_string s;
for(int i = 0; ; i++)
{
s = prof.get("Default", NULL, i);
if (s.empty())
break;
const int field = s.get_int();
((TTipo_documento*)this)->_defaults.add(s.get(), field);
}
}
return _defaults;
}
void TTipo_documento::set_defaults(TMask& m) const
{
const TString_array& def = get_defaults();
// Setta i campi della maschera
FOR_EACH_ARRAY_ROW(def, i, tt)
m.set(i, *tt, true);
}
void TTipo_documento::add_formula_if_needed(TConfig& profile, TString& variable,
const char* varname, const char* formula)
{
variable = profile.get(varname, "MAIN");
if (variable.blank())
variable = varname;
const TRectype& trr = cache().get("%FRD", variable);
if (trr.empty() || trr.get("S1").empty())
_formule_documento.add(variable, new TFormula_documento(_documento, variable, formula), TRUE);
if (_formule.find(variable) < 0)
_formule.add(variable);
}
void TTipo_documento::read_formule()
{
TFilename profile; profile_name(profile);
TConfig prof(profile, "MAIN");
prof.write_protect(); // Altrimenti non si distrugge!!!
_tipocr = prof.get_char("TIPOCR", NULL, -1, ' ');
_formule = prof.get("CAMPICALC");
const TString& calcoli = prof.get("CALCOLI");
if (calcoli == "*")
{
TTable frd("%FRD");
for (int err = frd.first(); err == NOERR; err = frd.next())
{
const TString & formula = frd.get("CODTAB");
if (_formule.find(formula) < 0)
_formule.add(formula);
}
}
else
_formule.add(calcoli);
add_formula_if_needed(prof, _totale, "TOTALE", "IMPONIBILI()+IMPOSTE()");
if (_totale == "TOTALE")
_totale = "TOTDOC";
_totale_netto = "_"; _totale_netto << _totale;
add_formula_if_needed(prof, _basesconto, "BASESCONTO", "SOMMA(\"IMPONIBILE()\", \"(TIPO()!='S') && (TIPO()!='C')\")");
add_formula_if_needed(prof, _spese, "SPESE", "SOMMA(\"IMPONIBILE()\", \"TIPO() == 'S'\")");
add_formula_if_needed(prof, _totvalres, "TOTVALRES", "VALDOC(0)");
add_formula_if_needed(prof, _totvalore, "TOTVALORE", "VALDOC(1)");
if (provvigioni())
{
TString80 campo(prof.get("TOTPROVV"));
if (campo.empty())
campo = "TOTPROVV";
const TRectype& frd = cache().get("%FRD", campo);
_totprovv = "_";
_totprovv << campo;
TString80 expr(frd.get("S1"));
if (expr.empty())
expr = "SOMMA(\"PROVV()\")";
_formule_documento.add(_totprovv, new TFormula_documento(_documento, _totprovv, expr, TRUE));
if (_formule.find(campo) < 0)
_formule.add(campo);
_formule.add(_totprovv);
_formule_documento.add(campo, new TFormula_documento(_documento, campo, "TOTPROVV()"), TRUE);
campo = prof.get("TOTPROVV1");
if (campo.empty())
campo = "TOTPROVV1";
const TRectype& frd1 = cache().get("%FRD", campo);
_totprovv1 = "_";
_totprovv1 << campo;
expr = frd1.get("S1");
if (expr.empty())
expr = "SOMMA(\"PROVV(-883,0)\")";
_formule_documento.add(_totprovv1, new TFormula_documento(_documento, _totprovv1, expr));
if (_formule.find(campo) < 0)
_formule.add(campo);
_formule.add(_totprovv1);
_formule_documento.add(campo, new TFormula_documento(_documento, campo, "TOTPROVV(-883,0)"));
}
_totale_cont = prof.get("TOTALECONT");
_cnt_prezzi = prof.get_bool("CONTROLLO_PREZZI");
_field_prezzo = prof.get(RDOC_PREZZO);
_field_qta = prof.get(RDOC_QTA, NULL, -1, RDOC_QTA);
_field_qtaevasa = prof.get(RDOC_QTAEVASA, NULL, -1, RDOC_QTAEVASA);
_field_qta_mag = prof.get("QTA_MAG");
if(_field_qta_mag.blank())
_field_qta_mag = _field_qta;
_field_qtaevasa_mag = prof.get("QTAEVASA_MAG");
if(_field_qtaevasa_mag.blank())
_field_qtaevasa_mag = _field_qtaevasa;
_check_qta = prof.get_char("CHECK_QTA", "MAIN");
_load_cont = prof.get_bool("LOAD_CONT", "MAIN");
_raee_cod = prof.get("RAEE_COD", "MAIN");
_raee_fld = prof.get("RAEE_FLD", "MAIN");
TToken_string str = prof.get("ART_TO_SHOW", "MAIN");
_liv = str.get_int();
_row = str.get_int();
if (_liv > 0 && _row == 0)
_row = 1;
_str_desc_doc = prof.get("DESCRIZIONE_DOC");
_str_desc_rdoc = prof.get("DESCRIZIONE_RDOC");
_show_evaded_lines = !prof.get_bool("NASCONDI_RIGHE_EVASE"); // Normalmente mostra anche evase
_non_evadere = prof.get_bool("NON_EVADERE"); // Normalmente mostra anche evase
_module = prof.get("MODULE", NULL, -1, "ve").left(2);
_hca_req = !prof.get_bool("HEAD_CA_OPT");
_check_double_art = prof.get_bool("CHECK_DOUBLE_ART");
_ignora_anticipi_fatturazione = prof.get_bool("IGNORA_ANTICIPI_FATTURAZIONE");
}
bool TTipo_documento::movimento_interno() const
{
const TString& elab = elaborazione();
if (elab.full())
{
const TString& app = cache().get("%ELD", elab, "S3");
return app.starts_with("ci1 -4", true);
}
return false;
}
bool TTipo_documento::stato_with_mov_mag(const char stato) const
{
if (!mov_mag())
return false;
const char stato_finale = stato_mov_finale();
if (stato_finale > ' ' && stato > stato_finale)
return false;
const char stato_iniziale = stato_mov_iniziale();
return stato >= stato_iniziale;
}
TFormula_documento* TTipo_documento::succ_formula(bool restart)
{
if (restart)
_formule.restart();
TString formula = _formule.get();
while (formula.not_empty())
{
if (formula.blank())
formula = _formule.get();
else
break;
}
if (formula.not_empty())
{
char *expr = NULL;
const int p = formula.find('=');
if (p > 0)
{
expr = (char *) (const char *) formula + p;
*expr = '\0'; expr++;
}
TFormula_documento* o = (TFormula_documento*)_formule_documento.objptr(formula);
if (o == NULL)
{
o = new TFormula_documento(_documento, formula, expr);
_formule_documento.add(formula, o);
}
return o;
}
return NULL;
}
bool TTipo_documento::scarica_residuo() const
{
if (is_ordine() && !riporta_ordinato())
return true;
return get_bool("B4");
}
///////////////////////////////////////////////////////////
// Espressione rdocumento
///////////////////////////////////////////////////////////
TExpr_documento::TExpr_documento(const char* expression, TTypeexp type,
const TDocumento* doc, const TRiga_documento* row)
: TExpression(type), _doc(doc), _row(row)
{
if (!set(expression, type))
error_box("Wrong expression : '%s'", expression);
}
int TExpr_documento::parse_user_func(const char * name, int nparms) const
{
if (strcmp(name, "SOMMA") == 0)
return nparms > 0 || nparms < 3 ? _somma : -1;
if (strcmp(name, "BOLLI") == 0)
return nparms > 0 || nparms < 4 ? _bolli : -1;
if (strcmp(name, "_BOLLI") == 0)
return nparms > 0 || nparms < 3 ? _bolli_int : -1;
if (strcmp(name, "SPESEINC") == 0)
return nparms > 0 || nparms < 4 ? _spinc : -1;
if (strcmp(name, "PREZZO") == 0)
return nparms < 4 ? _prezzo : -1;
if (strcmp(name, "IMPORTO") == 0)
return nparms < 4 ? _importo : -1;
if (strcmp(name, "SCONTO") == 0)
return nparms < 2 ? _sconto : -1;
if (strcmp(name, "IMPONIBILE") == 0)
return nparms == 0 ? _imponibile : -1;
if (strcmp(name, "IVA") == 0)
return nparms == 0 ? _iva : -1;
if (strcmp(name, "PROVV") == 0)
return nparms < 3 ? _provv : -1;
if (strcmp(name, "QUANT") == 0)
return nparms < 2 ? _quant : -1;
if (strcmp(name, "QUANTEVASA") == 0)
return nparms < 2 ? _quantevasa : -1;
if (strcmp(name, "QTARES") == 0)
return nparms < 2 ? _qtares : -1;
if (strcmp(name, "VALDOC") == 0)
return nparms < 3 ? _valdoc : -1;
if (strcmp(name, "TIPO") == 0)
return nparms == 0 ? _tipo : -1;
if (strcmp(name, "IMPONIBILI") == 0)
return nparms < 3 ? _imponibili : -1;
if (strcmp(name, "IMPOSTE") == 0)
return nparms < 3 ? _imposte : -1;
if (strcmp(name, "TOTPROVV") == 0)
return nparms < 3 ? _totprovv : -1;
if (strcmp(name, "PSCONTOT") == 0)
return nparms < 1 ? _pscontot : -1;
if (strcmp(name, "RITENUTA") == 0)
return nparms < 3 ? _ritenuta : -1;
if (strcmp(name, "TIPORIT") == 0)
return nparms < 1 ? _tipo_ritenuta : -1;
if (strcmp(name, "COMP") == 0)
return nparms == 2 ? _componente : -1;
if (strcmp(name, "COMPQTA") == 0)
return nparms == 2 ? _comp_qta : -1;
if (strcmp(name, "NRATE") == 0)
return nparms == 0 ? _nrate : -1;
return -1;
}
void TExpr_documento::evaluate_user_func(int index, int nparms, TEval_stack & stack, TTypeexp type) const
{
if (index >= _componente)
int i = 0;
switch (index)
{
case _somma:
{
const TString cond = nparms == 2 ? stack.pop_string() : "STR(1)";
const TString& field = stack.pop_string();
real sum;
if (_doc != NULL)
{
TExpr_documento cond_expr(cond, _strexpr, _doc);
const int cond_nvars = cond_expr.numvar();
TExpr_documento expr(field, _numexpr, _doc);
const int nvars = expr.numvar();
for (int i = _doc->rows(); i > 0; i--)
{
const TRiga_documento& riga = (const TRiga_documento&)(*_doc)[i];
for (int j = cond_nvars - 1; j >= 0; j--)
{
const char* s = cond_expr.varname(j);
const TFieldref f(s,0);
cond_expr.setvar(j, f.read(riga));
}
cond_expr.set_row(&riga);
if (cond_expr.as_bool())
{
for (int j = nvars - 1; j >= 0; j--)
{
const char* s = expr.varname(j);
const TFieldref f(s,0);
expr.setvar(j, f.read(riga));
}
expr.set_row(&riga);
sum += expr.as_real();
}
}
}
stack.push(sum);
}
break;
case _spinc:
{
int ndec = AUTO_DECIMALS;
bool netto = FALSE;
if (nparms > 2)
ndec = (int) stack.pop_real().integer();
if (nparms > 1)
netto = !stack.pop_real().is_zero();
real & r = stack.peek_real();
if (_doc)
r = _doc->spese_incasso(real(r - (const real)_doc->ritenute()), ndec, netto ? _netto : _lordo);
else
r = ZERO;
}
break;
case _bolli:
{
int ndec = AUTO_DECIMALS;
bool netto = FALSE;
if (nparms > 2)
ndec = (int) stack.pop_real().integer();
if (nparms > 1)
netto = !stack.pop_real().is_zero();
real & r = stack.peek_real();
if (_doc)
{
r += _doc->spese_incasso(real(r - _doc->ritenute()), ndec);
r = _doc->bolli(real(r - _doc->ritenute()), ndec, netto ? _netto : _lordo);
}
else
r = ZERO;
}
break;
case _bolli_int:
{
int ndec = AUTO_DECIMALS;
if (nparms > 2)
ndec = (int) stack.pop_real().integer();
real & r = stack.peek_real();
if (_doc)
{
real r1 = _doc->spese_incasso(real(r - _doc->ritenute()), ndec);
r += r1;
r1 += _doc->bolli(real(r - _doc->ritenute()), ndec);
r = r1;
}
else
r = ZERO;
}
break;
case _prezzo:
{
int ndec = AUTO_DECIMALS;
bool lordo = FALSE;
bool scontato = FALSE;
if (nparms > 2)
ndec = (int) stack.pop_real().integer();
if (nparms > 1)
lordo = !stack.pop_real().is_zero();
if (nparms > 0)
scontato = !stack.peek_real().is_zero();
else
stack.push(ZERO);
real & val = stack.peek_real();
if (_row)
val = _row->prezzo(scontato, lordo, ndec);
else
val = ZERO;
}
break;
case _importo:
{
int ndec = AUTO_DECIMALS;
bool lordo = FALSE;
bool scontato = FALSE;
if (nparms > 2)
ndec = (int) stack.pop_real().integer();
if (nparms > 1)
lordo = !stack.pop_real().is_zero();
if (nparms > 0)
scontato = !stack.peek_real().is_zero();
else
stack.push(ZERO);
real & val = stack.peek_real();
if (_row)
val = _row->importo(scontato, lordo, ndec);
else
val = ZERO;
}
break;
case _imponibile:
{
real r;
if (_row)
r = _row->imponibile();
stack.push(r);
}
break;
case _sconto:
{
int ndec = AUTO_DECIMALS;
if (nparms > 0)
ndec = (int) stack.peek_real().integer();
else
stack.push(ZERO);
real & val = stack.peek_real();
if (_row)
{
val = _row->importo(false, false, ndec);
if (_row->is_sconto())
val = -val;
else
val -= _row->importo(true, false, ndec);
}
else
val = ZERO;
}
break;
case _iva:
{
real r;
if (_row)
r = _row->imposta();
stack.push(r);
}
break;
case _provv:
{
int ndec = AUTO_DECIMALS;
bool first = true;
if (nparms > 1)
first = !stack.peek_real().is_zero();
if (nparms > 0)
ndec = (int) stack.peek_real().integer();
else
stack.push(ZERO);
real & val = stack.peek_real();
if (_row)
val = _row->provvigione(first, ndec);
else
val = ZERO;
}
break;
case _quant:
{
int ndec = AUTO_DECIMALS;
if (nparms > 0)
ndec = (int)stack.peek_real().integer();
else
stack.push(ZERO);
real& val = stack.peek_real();
if (_row)
val = _row->quantita();
else
val = ZERO;
}
break;
case _quantevasa:
{
int ndec = AUTO_DECIMALS;
if (nparms > 0)
ndec = (int)stack.peek_real().integer();
else
stack.push(ZERO);
real& val = stack.peek_real();
if (_row)
val = _row->qtaevasa();
else
val = ZERO;
}
break;
case _qtares:
{
int ndec = AUTO_DECIMALS;
if (nparms > 0)
ndec = (int) stack.peek_real().integer();
else
stack.push(ZERO);
real & val = stack.peek_real();
if (_row)
val = _row->qtaresidua();
else
val = ZERO;
}
break;
case _valdoc:
{
int ndec = AUTO_DECIMALS;
bool totale = TRUE; // Totale o residuo per documento
if (nparms > 1)
ndec = (int)stack.pop_real().integer();
if (nparms > 0)
totale = !stack.peek_real().is_zero();
else
stack.push(ZERO);
real & r = stack.peek_real();
if (_doc)
r = _doc->valore(totale, false, ndec);
else
r = ZERO;
}
break;
case _tipo:
{
TString s;
if (_row)
s << _row->tipo().tipo();
stack.push(s);
}
break;
case _imponibili:
{
int ndec = AUTO_DECIMALS;
bool spese = FALSE;
if (nparms > 1)
ndec = (int) stack.pop_real().integer();
if (nparms > 0)
spese = !stack.peek_real().is_zero();
else
stack.push(ZERO);
real & val = stack.peek_real();
val = _doc->imponibile(spese, ndec);
}
break;
case _imposte:
{
int ndec = AUTO_DECIMALS;
bool spese = FALSE;
if (nparms > 1)
ndec = (int) stack.pop_real().integer();
if (nparms > 0)
spese = !stack.peek_real().is_zero();
else
stack.push(ZERO);
real & val = stack.peek_real();
val = _doc->imposta(spese, ndec);
}
break;
case _totprovv:
{
int ndec = AUTO_DECIMALS;
bool first = true;
bool all = nparms == 0;
if (nparms > 1)
first = !stack.peek_real().is_zero();
if (nparms > 0)
ndec = (int) stack.peek_real().integer();
else
stack.push(ZERO);
real & val = stack.peek_real();
if (all)
val = _doc->provvigione(true, ndec) + _doc->provvigione(false, ndec);
else
val = _doc->provvigione(first, ndec);
}
break;
case _pscontot:
{
real val;
TString80 s;
if (_doc && scontoexpr2perc(_doc->get(DOC_SCONTOPERC), FALSE, s, val) && val != ZERO)
val = UNO - val;
stack.push(val);
}
break;
case _ritenuta:
{
int ndec = AUTO_DECIMALS;
bool lordo = FALSE;
if (nparms > 1)
ndec = (int) stack.pop_real().integer();
if (nparms > 0)
lordo = !stack.peek_real().is_zero();
else
stack.push(ZERO);
real & val = stack.peek_real();
if (_row && _row->tipo().tipo() == 'S')
{
const char tipo = _row->spesa().tipo_ritenuta();
val = _row->ritenuta(tipo, lordo, ndec);
}
else
val = ZERO;
}
break;
case _tipo_ritenuta:
{
TString s;
if (_row && _row->tipo().tipo() == 'S')
s << _row->spesa().tipo_ritenuta();
stack.push(s);
}
break;
case _componente:
case _comp_qta:
{
static TAssoc_array comps;
static TAssoc_array qtas;
const TString substr = stack.pop_string();
const int pos = atoi(stack.pop_real().string());
const TString codart = _row->get(RDOC_CODARTMAG);
TString * val = (TString *) comps.objptr(codart);
if (val != NULL)
{
if (index == _componente)
stack.push(*val);
else
{
const real &val = *(real *) qtas.objptr(codart);
stack.push(val);
}
}
else
{
TDistinta_tree db;
TArray comp;
bool found = false;
db.set_root(codart);
const int items = db.explode(comp, true, RAGGR_EXP_UMBASE, 0, "A", false);
if (items > 0)
{
for (int i = comp.first(); !found && i < items; i = comp.succ(i))
{
TRiga_esplosione& r = (TRiga_esplosione &) comp[i];
const TCodice_articolo c = r.articolo();
if (c.find(substr, pos) > 0)
{
if (index == _componente)
stack.push(c);
else
stack.push(r.val());
comps.add(codart, c);
qtas.add(codart, r.val());
found = true;
}
}
}
if (!found)
{
if (index == _componente)
stack.push(EMPTY_STRING);
else
stack.push(ZERO);
comps.add(codart, EMPTY_STRING);
qtas.add(codart, ZERO);
}
}
}
break;
case _nrate:
{
const TPagamento& p = ((TDocumento*)_doc)->pagamento();
const real r = p.n_rate();
stack.push(r);
}
break;
default:
TExpression::evaluate_user_func(index, nparms, stack, type);
break;
}
}
TObject* TExpr_documento::dup() const
{
TExpr_documento* o = new TExpr_documento(*this);
return o;
}
///////////////////////////////////////////////////////////
// Formula documento
///////////////////////////////////////////////////////////
TFormula_documento::TFormula_documento(TTipo_formula tipo, const char* codice, const char * expr, bool numexpr)
: TRectype(LF_TABCOM), _expr(NULL)
{
settab(tipo == _documento ? "FRD" : "FRR");
if (codice && *codice)
read(codice, expr, numexpr);
}
TFormula_documento::TFormula_documento(const TRectype& rec)
: TRectype(rec), _expr(NULL)
{
const TTypeexp et = expr_type();
_expr = new TExpr_documento(expr_string(), et);
}
TFormula_documento::~TFormula_documento()
{
if (_expr)
delete _expr;
}
int TFormula_documento::read(const char* codice, const char * expr, bool numexpr)
{
if (_expr != NULL)
{
delete _expr;
_expr = NULL;
}
put("CODTAB", codice);
int err = NOERR;
if (expr && *expr)
{
put("S1", expr);
put("B0", numexpr ? "X" : "");
}
else
{
TString4 cod; cod << '%' << get("COD");
TTable t(cod);
err = TRectype::read(t);
}
if (err == NOERR)
{
const TTypeexp et = expr_type();
const TString& e = expr_string(); // Copio espressione proveniente da record
_expr = new TExpr_documento(e, et);
}
else
{
zero();
put("CODTAB", codice);
}
return err;
}
//roba usata in CI ed LV (per ora, 21/01/2011)
////////////////////////
//// TDOC_KEY ////
////////////////////////
//CODNUM: metodo che restituisce il provv dalla TToken_string chiave dei documenti
const char TDoc_key::provv() const
{
return (*this)[0];
}
//ANNO: metodo che restituisce l'anno dalla TToken_string chiave dei documenti
const int TDoc_key::anno() const
{
int anno = 0; get(1, anno);
return anno;
}
//CODNUM: metodo che restituisce il codnum dalla TToken_string chiave dei documenti
const char* TDoc_key::codnum() const
{
TString& codnum = get_tmp_string();
get(2, codnum);
return codnum;
}
//NDOC: metodo che restituisce il numero documento dalla TToken_string chiave dei documenti
const long TDoc_key::ndoc() const
{
long n = 0; get(3, n);
return n;
}
//SET_PROVV: metodo che setta il campo provv
void TDoc_key::set_provv(const char provv)
{
add(provv, 0);
}
//SET_ANNO: metodo che setta il campo anno
void TDoc_key::set_anno(const int anno)
{
add(anno, 1);
}
//SET_CODNUM: metodo che setta il campo codnum
void TDoc_key::set_codnum(const char* codnum)
{
add(codnum, 2);
}
//SET_NDOC: metodo che setta il campo ndoc
void TDoc_key::set_ndoc(const long ndoc)
{
add(ndoc, 3);
}
//metodi costruttori
TDoc_key::TDoc_key(const int anno, const TString& codnum, const long ndoc, const char provv)
{
add(provv);
add(anno);
add(codnum);
add(ndoc);
}
TDoc_key::TDoc_key(const TRectype& rec)
{
switch (rec.num())
{
case LF_MOVMAG:
add(rec.get_char(MOVMAG_DOCPROVV));
add(rec.get_int(MOVMAG_ANNODOC));
add(rec.get(MOVMAG_CODNUM));
add(rec.get_long(MOVMAG_NUMDOC));
break;
default:
add(rec.get_char(DOC_PROVV));
add(rec.get_int(DOC_ANNO));
add(rec.get(DOC_CODNUM));
add(rec.get_long(DOC_NDOC));
break;
}
}
/////////////////////////
//// TRDOC_KEY ////
/////////////////////////
const int TRdoc_key::nriga() const
{
int riga = 0; get(4, riga);
return riga;
}
//metodi costruttori
TRdoc_key::TRdoc_key(const int anno, const TString& codnum, const long ndoc, const int nriga, const char provv)
: TDoc_key(anno, codnum, ndoc, provv)
{
add(nriga, 4);
}
TRdoc_key::TRdoc_key(const TRectype& rec)
{
switch (rec.num())
{
case LF_RIGHEDOC:
default:
add(rec.get(RDOC_PROVV));
add(rec.get(RDOC_ANNO));
add(rec.get(RDOC_CODNUM));
add(rec.get(RDOC_NDOC));
add(rec.get(RDOC_NRIGA));
break;
}
}