campo-sirio/cg/cglib01.cpp
guy b8028b2bf2 Patch level : 2.0 470
Files correlati     : cg1.exe cg2.exe cg3.exe cg3100a.msk cg3600a.msk cg3600b.msk cg4700a.msk
Ricompilazione Demo : [ ]
Commento            :

EP20036
Richiamo registrazione fatt. vendita già inserita, vado alla pagina IVA
col mouse mi posiziono sul campo "CR"cerco di entrare nella list box
associata al campo. Errore dell'applicazione cg2.exe* (l'errore può non
comparire subito ma dopo essere usciti dalla registrazione contabile avendo
eseguito quando descritto sopra e poi rientrati ripetendo il tutto.)Win 2000

EP20039
Compilo la maschera fino al group box "Intesta deleghe a", col mouse mi
posiziono sul campo Tipo e cerco di entrare nella list box associata al
campo: Errore CG1.exe

EP20040
Col mouse: mi posiziono  sul campo "Stampa dal registro IVA" entro nella
tabella registri associata al campo mi posiziono sulla riga del registro
iva vendite e clicco sul bottone collega: la procedura ritorna nella
maschera Lista movimenti anziché entrare nella tabella registri

EP20042
Lavoro col mouse: richiamo un movimento inserito con causale V01 abilitata
al saldaconto, vado alla pagina Scadenze e mi posiziono sul campo Ns. Banca
ABI.Entro nella tabella banche associata al campo, seleziono una banca
inserita e clicco sul bottone collega.Ritorno alla pagina scadenze del
movimento contabile.

EP20044
Se in file impostazione stampante è indicato stampa su... Visualizzazione,
la stampa viene visualizzata correttamente ma non esce stampa su carta.

EP20045
Correzione righe di prima nota, digito la password e clicco su conferma,
mi propone la ditta 1 e clicco su selezione, compare maschera righe di
prima nota errata vuota clicco sul bottone tutti errore dell'applicazione
cg1.exe n.b. anche nella versione1.7(E' corretto che il bottone Tutti sia attivo?)

EP20051
Col mouse: clicco sul bottone di ricerca richiamo conto 1 1 1 mi posiziono
sul campo "codice tabella analisi" ed entro nella tabella associata al
campo clicco sul bottone nuovo errore: impossibile trovare CB5.DLL

EP20053
Se in file impostazione stampante è indicato stampa su... Visualizzazione
la stampa viene visualizzata correttamente ma non esce stampa su carta.

EP20059
Ho inserito n clienti. Clicco sul bottone di ricerca e richiamo un cliente
già registrato. Clicco sulla freccina singola a sx del botone ricerca
(e anche sulle altre freccie): messaggo "vuoi registrare dati inseriti?"

EP20060
Il bottone ricerca non ha "freccie avanti-dietro"
NON DEVE AVERLO!  NON E' UN PROGRAMMA DI IMMISSIONE DATI

EP20061
Il bottone ricerca non ha "freccie avanti-dietro"
NON DEVE AVERLO!  NON E' UN PROGRAMMA DI IMMISSIONE DATI

EP20063
entrando nella voce tabella piano dei conti errore impossibile trovare CB5.DLL

EP20073
all'interno dei campi (es.numero protocollo) il comando di tastiera "canc" non funziona

EP20076
Richiamo un'anagrafica già inserita clicco su nuovo messaggio :"registrare le modifiche?"


git-svn-id: svn://10.65.10.50/trunk@11127 c028cbd2-c16b-5b4b-a496-9718f37d4682
2003-05-14 13:12:14 +00:00

932 lines
20 KiB
C++
Executable File
Raw Blame History

// Esercizi contabili e registri IVA
#include <currency.h>
#include <diction.h>
#include <mask.h>
#include <prefix.h>
#include <recarray.h>
#include <relation.h>
#include <tabutil.h>
#include <utility.h>
#include <diction.h>
#include <pconti.h>
#include <rmov.h>
#include <rmoviva.h>
#include "cglib01.h"
///////////////////////////////////////////////////////////
// Gestione Tabella esercizi
///////////////////////////////////////////////////////////
TArray TEsercizi_contabili::_esercizi;
long TEsercizi_contabili::_firm = 0;
TEsercizio::TEsercizio(const TRectype& rec)
{
_codice = rec.get_int("CODTAB");
_inizio = rec.get("D0");
_fine = rec.get("D1");
_scarico = rec.get("D2");
_chiusura = rec.get("D3");
_chiusura_mag = rec.get("D4");
}
int TEsercizio::compare(const TSortable& s) const
{
const TEsercizio& e = (const TEsercizio&)s;
int c = 0;
if (_inizio != e._inizio)
c = _inizio > e._inizio ? +1 : -1;
return c;
}
TEsercizi_contabili::TEsercizi_contabili()
{
}
void TEsercizi_contabili::update()
{
_firm = prefix().get_codditta();
_esercizi.destroy();
TTable tab_esc("ESC");
for (int err = tab_esc.first(); err == NOERR; err = tab_esc.next())
{
TEsercizio* e = new TEsercizio(tab_esc.curr());
_esercizi.add(e);
}
_esercizi.sort();
}
void TEsercizi_contabili::check()
{
if (_firm != prefix().get_codditta())
update();
}
int TEsercizi_contabili::date2index(const TDate& d) const
{
check();
for (int i = items()-1; i >= 0; i--)
{
const TEsercizio& e = esc(i);
if (d >= e.inizio() && d <= e.fine())
break;
}
return i;
}
int TEsercizi_contabili::esc2index(int codice) const
{
check();
for (int i = items()-1; i >= 0; i--)
{
const TEsercizio& e = esc(i);
if (codice == e.codice())
break;
}
return i;
}
int TEsercizi_contabili::date2esc(const TDate& d) const
{
const int i = date2index(d);
return i >= 0 ? esc(i).codice() : 0;
}
int TEsercizi_contabili::date2prevesc(const TDate& d) const
{
const int i = date2index(d);
return i > 0 ? esc(i - 1).codice() : 0;
}
int TEsercizi_contabili::date2nextesc(const TDate& d) const
{
const int i = date2index(d);
return i >=0 && i < items()-1 ? esc(i+1).codice() : 0;
}
int TEsercizi_contabili::first() const
{
check();
return items() ? esc(0).codice() : 0;
}
int TEsercizi_contabili::last() const
{
check();
return items() ? esc(items()-1).codice() : 0;
}
// Certified 99%
int TEsercizi_contabili::last_mag() const
{
/* Vecchio modo error-prone che non funziona nel primo anno di attivit<69>
int es=last()-1;
while (es>0 && !esercizio(es).chiusura_mag())
es--;
es++;
*/
check();
for (int i = items()-1; i >= 0; i--)
{
const TEsercizio& e = esc(i);
if (e.chiusura_mag().ok())
break;
}
return esc(i+1).codice();
}
int TEsercizi_contabili::pred(int codice) const
{
const int i = esc2index(codice);
return i > 0 ? esc(i-1).codice() : 0;
}
int TEsercizi_contabili::next(int anno) const
{
const int i = esc2index(anno);
return i < items()-1 ? esc(i+1).codice() : 0;
}
bool TEsercizi_contabili::exist(int codice) const
{
const int i = esc2index(codice);
return i >= 0;
}
const TEsercizio& TEsercizi_contabili::esercizio(int codice) const
{
const int i = esc2index(codice);
return esc(i);
}
const char* iva2name(TipoIVA iva)
{
const char* i;
switch(iva)
{
case nessuna_iva:
i = TR("Nessuna IVA"); break;
case iva_acquisti:
i = TR("IVA Acquisti"); break;
case iva_vendite:
i = TR("IVA Vendite"); break;
case iva_generica:
i = TR("IVA Generica"); break;
default:
i = TR("IVA ERRATA!"); break;
}
return i;
}
///////////////////////////////////////////////////////////
// Registro
///////////////////////////////////////////////////////////
TRegistro::TRegistro(const char* cod, int year)
: _rec(LF_TAB), _att(LF_ATTIV)
{
read(cod, year);
}
bool TRegistro::read(const char* cod, int year)
{
if (year <= 0)
{
const TDate oggi(TODAY);
year = oggi.year();
}
if (cod == NULL)
cod = "";
TString16 chiave; chiave.format("%04d%s", year, cod);
_rec = cache().get("REG", chiave);
read_att();
return !_rec.empty();
}
bool TRegistro::reread()
{
if (ok())
{
const TString16 n(name());
const int y = year();
return read(n, y);
}
return FALSE;
}
int TRegistro::year() const
{
TString16 anno(_rec.get("CODTAB"));
anno.cut(4);
return atoi(anno);
}
const TString& TRegistro::name() const
{
return _rec.get("CODTAB").mid(4);
}
TRegistro& TRegistro::operator =(const TRegistro& r)
{
_rec = r._rec;
_att = r._att;
_prorata = r._prorata;
return *this;
}
int TRegistro::tipo() const
{
const int t = _rec.get_int("I0");
return t;
}
bool TRegistro::corrispettivi() const
{
const bool c = _rec.get_bool("B0");
return c;
}
TipoIVA TRegistro::iva() const
{
TipoIVA i = (TipoIVA)tipo();
switch (i)
{
case nessuna_iva:
case iva_vendite:
case iva_acquisti:
break;
case libro_giornale:
i = nessuna_iva;
break;
default:
error_box(FR("Il registro '%s' non e' un registro IVA o contabile: tipo %d"),
(const char*)name(), i);
i = nessuna_iva;
break;
}
return i;
}
bool TRegistro::read_att()
{
TString16 chiave;
chiave << prefix().get_codditta() << '|' << attivita();
_att = cache().get(LF_ATTIV, chiave);
// Ditta - Anno - Attivita' - Tipo Attivita' (fissata a 1)
chiave.format("%05ld", prefix().get_codditta());
chiave << year(); // non fare << year() << attivita()
chiave << attivita() << "1";
_prorata.destroy();
const TRectype & pla = cache().get("%PLA", chiave);
if (!pla.empty())
{
chiave.format("%d", year());
_prorata.add(chiave, pla.get_real("R8"));
_att.put("TIPOATT", pla.get("S7")); // Aggiorna tipo attivita'
}
return !_att.empty();
}
bool TRegistro::agenzia_viaggi()
{
bool av = FALSE;
if (iva() == iva_vendite)
av = _att.get_bool("REG74TER");
return av;
}
const TString& TRegistro::tipo_attivita()
{
return _att.get("TIPOATT");
}
real* TRegistro::read_prorata(int anno) const
{
TString16 chiave; // Ditta - Anno - Attivita' - Tipo Attivita' (fissata a 1)
chiave.format("%05ld", prefix().get_codditta());
chiave << anno << attivita() << "1";
real* prorata = NULL;
const TRectype& pla = cache().get("%PLA", chiave);
if (!pla.empty())
prorata = new real(pla.get("R8"));
return prorata;
}
real TRegistro::prorata(int annodoc)
{
const int annoiva = year();
if (annodoc <= 1900) annodoc = annoiva; // Test per anno documento non specificato
const int annopro = annoiva >= 1998 && annodoc < annoiva ? annodoc+1 : annoiva;
TString16 chiave; chiave << annopro;
real* pr = (real*)_prorata.objptr(chiave);
if (pr == NULL)
{
pr = read_prorata(annopro);
if (pr == NULL && annopro != annoiva)
pr = read_prorata(annoiva);
if (pr == NULL)
pr = new real(ZERO);
_prorata.add(chiave, pr, TRUE);
}
return *pr;
}
void TRegistro::set_prorata(int annodoc, const real& pro)
{
const int annoiva = year();
if (annodoc <= 1900) annodoc = annoiva; // Test per anno documento non specificato
const int annopro = annoiva >= 1998 && annodoc < annoiva ? annodoc+1 : annoiva;
TString16 chiave; chiave << annopro;
_prorata.add(chiave, pro, TRUE);
}
// Certified 99%
bool TRegistro::update(long protiva, const TDate& datareg)
{
bool updated = TRUE;
if (protiva > _rec.get_long("I5"))
{
_rec.put("I5", protiva);
updated = FALSE;
}
if (datareg > _rec.get_date("D2"))
{
_rec.put("D2", datareg);
updated = FALSE;
}
if (!updated)
{
TTable reg("REG");
updated = reg.rewrite(_rec) == NOERR;
cache().discard(_rec); // Forza rilettura registro in cache
}
return updated;
}
///////////////////////////////////////////////////////////
// Libro giornale
///////////////////////////////////////////////////////////
// Legge il libro giornale dell'anno specificato
bool TLibro_giornale::read(int y)
{
bool found = FALSE;
if (y <= 0)
{
const TDate oggi(TODAY);
y = oggi.year();
}
TString16 anno; anno.format("%04d", y);
TTable reg("REG");
reg.put("CODTAB", anno); // Cerca il primo registro dell'anno
for (int err = reg.read(_isgteq); err == NOERR; err = reg.next())
{
if (reg.get("CODTAB").compare(anno, 4) != 0)
break; // Sono arrivato all'anno dopo
if (reg.get_int("I0") == libro_giornale)
{
found = TRUE;
break;
}
}
if (!found) reg.zero(); // Memorizza record (anche vuoto)
_rec = reg.curr();
return found;
}
TLibro_giornale::TLibro_giornale(int y)
{
read(y);
}
///////////////////////////////////////////////////////////
// Codice IVA
///////////////////////////////////////////////////////////
TCodiceIVA::TCodiceIVA(const char* cod) : TRectype(LF_TABCOM)
{
read(cod);
}
bool TCodiceIVA::read(const char* cod)
{
if (cod && *cod)
*this = cache().get("%IVA", cod);
else
zero();
return !empty();
}
real TCodiceIVA::imposta(const real & imponibile, int ndec, const char * codval) const
{
const real percent = percentuale();
real iva = imponibile * percent / 100.0;
switch (ndec)
{
case AUTO_DECIMALS:
ndec = TExchange(codval).decimals(FALSE);
break;
case AUTO_PRICES_DECIMALS:
ndec = TExchange(codval).decimals(TRUE);
break;
default:
break;
}
if (ndec < 20)
{
if (ndec == 0)
{
if (imponibile > ZERO)
iva.ceil(ndec);
else
iva.floor(ndec);
}
else
iva.round(ndec);
}
return iva;
}
real TCodiceIVA::scorpora(real& lordo, int ndec, const char* codval) const
{
const real percent = percentuale();
real iva = (lordo * percent) / (percent + 100.0);
real imponibile = lordo - iva;
switch (ndec)
{
case AUTO_DECIMALS:
ndec = TExchange(codval).decimals(FALSE);
break;
case AUTO_PRICES_DECIMALS:
ndec = TExchange(codval).decimals(TRUE);
break;
default:
break;
}
if (ndec < 20) // E' richiesto un arrotondamento significativo?
{
lordo.round(ndec); // Arrotondo importo lordo
if (ndec == 0) // Probabile caso Lire: arrotondo per eccesso l'IVA
{
if (imponibile > ZERO)
iva.ceil(ndec);
else
iva.floor(ndec);
}
else
iva.round(ndec); // Probabile caso Euro: arrotondo matematicamente l'IVA
imponibile.round(ndec); // Arrotondo imponibile
real diff = lordo - imponibile - iva;
diff.round(ndec); // Arrotondo la differenza (importantissimo per evitare valori del tipo 1E-18)
if (!diff.is_zero())
{
if (iva.sign() == diff.sign()) // Faccio crescere l'iva o l'imponibile ?
iva += diff;
else
imponibile += diff;
}
}
lordo = imponibile; // lordo <20> un reference da aggiornare con l'imponibile!
return iva;
}
real TCodiceIVA::lordo(const real & imponibile, int ndec, const char * codval) const
{
return imponibile + imposta(imponibile, ndec, codval);
}
bool handler_data_cambio(TMask_field& f, KEY k)
{
return TRUE;
}
///////////////////////////////////////////////////////////
// TBill
///////////////////////////////////////////////////////////
TBill::~TBill()
{
if (_descrizione)
delete _descrizione;
}
void TBill::set_description(const char* d)
{
if (_descrizione || (d && *d))
{
if (_descrizione)
*_descrizione = d;
else
_descrizione = new TString(d);
}
}
// Certified 90%
const TBill& TBill::get(TToken_string& s, int from, int mode)
{
const char* first = s.get(from);
if (mode & 0x1)
{
_tipo = first ? char(toupper(*first)) : ' ';
first = s.get();
} else _tipo = ' ';
#ifdef DBG
if (strchr(" CF", _tipo) == NULL)
{
error_box(FR("Tipo conto errato: '%c'"), _tipo);
_tipo = ' ';
}
#endif
_gruppo = first ? atoi(first) : 0;
_conto = s.get_int();
_sottoconto = s.get_long();
if (mode & 0x2)
set_description(s.get());
_tipo_cr = -1;
_sezione = ' ';
return *this;
}
const TBill& TBill::copy(const TBill& bill)
{
_tipo = bill._tipo;
_gruppo = bill._gruppo;
_conto = bill._conto;
_sottoconto = bill._sottoconto;
set_description(bill.descrizione());
_tipo_cr = bill._tipo_cr;
_sospeso = bill._sospeso;
_sezione = bill._sezione;
return *this;
}
// Certified 100%
const TBill& TBill::set(int g, int c, long s, char t, const char* d, int r)
{
_tipo = (t > ' ') ? char(toupper(t)) : ' ';
_gruppo = g;
_conto = c;
_sottoconto = s;
set_description(d);
_tipo_cr = r;
return *this;
}
const TBill& TBill::add_to(TToken_string& ts, int from, int mode)
{
if (mode & 0x4)
{
const int cr = tipo_cr();
if (cr > 0) ts.add(cr, from++); else ts.add(" ", from++);
}
if (mode & 0x1)
ts.add(_tipo, from++);
if (_gruppo > 0) ts.add(_gruppo, from++); else ts.add(" ", from++);
if (_conto > 0) ts.add(_conto, from++); else ts.add(" ", from++);
if (_sottoconto > 0L) ts.add(_sottoconto, from++); else ts.add(" ", from++);
if (mode & 0x2)
ts.add(descrizione(), from++);
return *this;
}
const char* TBill::field_name(int n, bool contro) const
{
CHECKD(n >= 0 && n <= 3, "Invalid bill field ", n);
const char* f;
if (contro)
{
switch(n)
{
case 0: f = RMV_GRUPPOC; break;
case 1: f = RMV_CONTOC; break;
case 2: f = RMV_SOTTOCONTOC; break;
default:f = RMV_TIPOCC; break;
}
}
else
{
switch(n)
{
case 0: f = RMV_GRUPPO; break;
case 1: f = RMV_CONTO; break;
case 2: f = RMV_SOTTOCONTO; break;
default:f = RMV_TIPOC; break;
}
}
return f;
}
void TBill::put(TRectype& r, bool c) const
{
r.put(field_name(0, c), gruppo());
r.put(field_name(1, c), conto());
r.put(field_name(2, c), sottoconto());
r.put(field_name(3, c), tipo());
}
bool TBill::get(const TRectype& r, bool c)
{
set(r.get_int(field_name(0, c)),
r.get_int(field_name(1, c)),
r.get_long(field_name(2, c)),
r.get_char(field_name(3, c)));
set_description(NULL);
_tipo_cr = -1;
_sezione = ' ';
if (r.num() == LF_RMOVIVA)
tipo_cr(r.get_int(RMI_TIPOCR));
return ok();
}
void TBill::set(TMask& m, short g, short c, short s, short t, short d) const
{
m.set(g, gruppo());
m.set(c, conto());
m.set(s, sottoconto());
if (t)
{
char typ[2] = { tipo(), '\0' };
m.set(t, typ);
}
if (d)
m.set(d, descrizione());
}
void TBill::get(const TMask& m, short g, short c, short s, short t, short d)
{
const int gr = m.get_int(g);
const int co = m.get_int(c);
const long so = m.get_long(s);
char ti = ' ';
if (t)
ti = m.get(t)[0];
TString80 de;
if (d)
de = m.get(d);
set(gr, co, so, ti, de);
}
// Certified 100%
bool TBill::ok() const
{
return _gruppo != 0 && _conto != 0 && _sottoconto != 0L;
}
// Certified 99%
int TBill::compare(const TSortable& s) const
{
CHECK(class_name()==s.class_name(), "Can't compare TBill with TObject");
const TBill& c = (const TBill&)s;
int res = _gruppo - c._gruppo;
if (res) return res;
res = _conto - c._conto;
if (res) return res;
const long lres = _sottoconto - c._sottoconto;
if (lres < 0L) res = -1; else
if (lres > 0L) res = +1;
return res;
}
// Certified 95%
bool TBill::find()
{
bool ok = FALSE;
if ((_tipo != 'C' && _tipo != 'F') || _sottoconto == 0L)
{
TRectype pcon(LF_PCON);
ok = read(pcon);
if (!ok && _sottoconto != 0L)
{
const long sotto = _sottoconto;
_sottoconto = 0L;
if (read(pcon))
_tipo = char(toupper(pcon.get_char(PCN_TMCF)));
_sottoconto = sotto;
}
}
if ((_tipo == 'C' || _tipo == 'F') && _sottoconto != 0L)
{
TString16 key;
key.format("%c|%ld", _tipo, _sottoconto);
const TRectype & clifo = cache().get(LF_CLIFO, key);
ok = !clifo.empty();
if (ok)
{
set_description(clifo.get("RAGSOC"));
if (_tipo_cr < 0)
{
_tipo_cr = 0;
_sezione = ' ';
}
_sospeso = clifo.get_bool("SOSPESO");
const char tipoa = clifo.get_char("TIPOPERS");
if (tipoa == 'F') // Se persona fisica allora aggiusta la ragione sociale
{
TString nome(descrizione().mid(30));
if (nome.not_empty())
{
_descrizione->cut(30);
_descrizione->trim(); nome.trim();
*_descrizione << ' ' << nome;
}
}
if (_gruppo == 0 || _conto == 0)
{
_gruppo = clifo.get_int("GRUPPO");
_conto = clifo.get_int("CONTO");
}
}
}
return ok;
}
bool TBill::read(TRectype &r)
{
bool ok = FALSE;
if (tipo() <= ' ' || sottoconto() <= 0)
{
TString16 key; key.format("%d|%d|%ld", gruppo(), conto(), sottoconto());
const TRectype& pcon = cache().get(LF_PCON, key);
if (!pcon.empty())
{
r = pcon;
ok = TRUE;
}
}
if (ok)
{
_tipo_cr = r.get_int(PCN_TIPOSPRIC);
_sezione = r.get_char(PCN_SEZSALDI);
set_description(r.get(PCN_DESCR));
_sospeso = r.get_bool(PCN_SOSPESO);
}
else
r.zero();
return ok;
}
int TBill::tipo_att()
{
int tipo_att = 1;
if (tipo() <= ' ' && ok())
{
TBill bill(gruppo(), conto());
TRectype rec(LF_PCON); bill.read(rec);
const TIndbil ib = (TIndbil)rec.get_int(PCN_INDBIL);
if (ib == ib_passivita || ib == ib_ricavi)
{
read(rec);
const int ricser = rec.get_int(PCN_RICSER); // 0 = Altre attivita 1 = Servizi
tipo_att = (ricser == 1) ? 1 : 2;
}
}
return tipo_att;
}
// Certified 99%
const TString& TBill::descrizione() const
{
TBill& myself = (TBill&)*this;
// Se il conto e' valido (c'e' almeno il gruppo) cerca la sua descrizione su file
if ((_descrizione == NULL || _descrizione->blank()) && gruppo() != 0)
{
if (!myself.find())
myself.set_description(TR("Sconosciuto"));
}
return _descrizione ? *_descrizione : (const TString&) EMPTY_STRING;
}
int TBill::tipo_cr() const
{
if (_tipo_cr < 0)
{
TBill& myself = (TBill&)*this;
myself.find();
}
return _tipo_cr;
}
bool TBill::sospeso() const
{
if (_tipo_cr < 0) tipo_cr(); // trick to load _sospeso
return _sospeso;
}
char TBill::sezione() const
{
if (_sezione == ' ') tipo_cr(); // trick to load _sezione
return _sezione;
}
// Certified 100%
const char* TBill::string(int mode) const
{
TString& s = get_tmp_string();
if (mode & 0x4)
{
const int cr = tipo_cr();
if (cr > 0) s << cr << '|';
else s << " |";
}
if (mode & 0x1)
s << _tipo << '|';
if (_gruppo > 0) s << _gruppo << '|';
else s << " |";
if (_conto > 0) s << _conto << '|';
else s << " |";
if (_sottoconto > 0L) s << _sottoconto;
else s << ' ';
if (mode & 0x2)
s << '|' << descrizione();
return s;
}
bool TBill::default_cdc(TString& cdc, TString& fas) const
{
bool ok = tipo() <= ' ' && sottoconto() > 0;
if (ok)
{
TString16 key; key.format("%d|%d|%ld", gruppo(), conto(), sottoconto());
const TRectype& pcon = cache().get(LF_PCON, key);
ok = !pcon.empty();
if (ok)
{
cdc = pcon.get(PCN_CODCMS);
fas = pcon.get(PCN_FASCMS);
}
}
return ok && cdc.not_empty();
}