campo-sirio/ve/velib01.cpp

336 lines
8.3 KiB
C++
Raw Normal View History

#include "velib.h"
/////////////////////////////////////////////////////////////
// TCodice_numerazione
/////////////////////////////////////////////////////////////
TCodice_numerazione::TCodice_numerazione(const char* codnum)
: TRectype(LF_TABCOM)
{
settab("NUM");
if (codnum && *codnum)
read(codnum);
else
setempty(TRUE);
}
TCodice_numerazione::TCodice_numerazione(const TRectype& rec)
: TRectype(rec)
{ }
TCodice_numerazione::~TCodice_numerazione()
{ }
const TString& TCodice_numerazione::tipo_doc(int i) const
{
CHECK(i < 36, "Impossibbile tipo documento");
const char * field = i < 17 ? "S2" : "S3";
if (i >= 17)
i -= 17;
TString & tmp = get_tmp_string();
tmp = get(field).mid(i * 4, 4);
tmp.trim();
return tmp;
}
int TCodice_numerazione::ntipi_doc() const
{
int l = get("S3").len();
if (l > 0)
return ((l - 1) / 4) + 18;
l = get("S2").len();
return l ? (((l - 1) / 4) + 1) : 0;
}
void TCodice_numerazione::complete_num(long num, TString& codnum) const
{
codnum = prefisso();
codnum << num;
codnum << postfisso();
}
int TCodice_numerazione::read(const char* codnum)
{
*this = cache().get("%NUM", codnum);
int err = empty() ? _iskeynotfound : NOERR;
#ifdef DBG
if (err != NOERR)
NFCHECK("Codice numerazione errato: %s", codnum);
#endif
return err;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// trova le numerazioni documenti in base ai tipi richiesti (ca3800,ca3900,ps1001)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int numerazioni_documenti(TString_array& num_doc, TString_array& tip_doc, const int tipo)
{
//cominciamo con i tipi
TISAM_recordset tipi_recset("USE %TIP\nSELECT STR(I1=#TIPO)");
tipi_recset.set_var("#TIPO", TVariant(long(tipo)));
for (bool ok = tipi_recset.move_first(); ok; ok = tipi_recset.move_next()) //giro sui vari tipi ordine
{
const TString4 tipo = tipi_recset.get("CODTAB").as_string();
tip_doc.add(tipo);
}
//e adesso cerca le numerazioni che contengono tipi ordine
TISAM_recordset num_recset("USE %NUM");
for (bool ok = num_recset.move_first(); ok; ok = num_recset.move_next()) //giro sui vari tipi numerazione
{
const TString4 codtab = num_recset.get("CODTAB").as_string();
const TCodice_numerazione numerazione(codtab);
for (int t = numerazione.ntipi_doc() - 1; t >= 0; t--)
{
const TString& tipo_doc = numerazione.tipo_doc(t);
if (tip_doc.find(tipo_doc) >= 0)
{
if (num_doc.find(codtab) < 0) // Evito aggiunta di doppioni
num_doc.add(codtab);
break;
}
} //for (int t = codnum..
} //for (bool ok = num_recset...
return num_doc.items();
}
int numerazioni_ordini(TString_array& num_ordini, TString_array& tip_ordini)
{
//i documenti che vanno presi in cosiderazione sono quelli che generano un IMPEGNATO secondo le auree regole del..
//..nostro invincibile Adolf!
num_ordini.destroy();
tip_ordini.destroy();
numerazioni_documenti(num_ordini, tip_ordini, 3);
return num_ordini.items();
}
int numerazioni_fatture(TString_array& num_fatture, TString_array& tip_fatture)
{
//i documenti che vanno presi in cosiderazione sono quelli non ancora contabilizzati di tipo 0=Altro 2=Fattura
num_fatture.destroy();
tip_fatture.destroy();
numerazioni_documenti(num_fatture, tip_fatture, 0);
numerazioni_documenti(num_fatture, tip_fatture, 2);
return num_fatture.items();
}
/////////////////////////////////////////////////////////////
// TSpesa_prest
/////////////////////////////////////////////////////////////
TSpesa_prest::TSpesa_prest(const char* codice, char tipo)
: TRectype(LF_TAB)
{
switch (tipo)
{
case RIGA_SPESEDOC :
settab("SPP");
break;
case RIGA_PRESTAZIONI :
settab("PRS");
break;
case RIGA_RISORSE :
settab("RSS");
break;
case RIGA_ATTREZZATURE :
settab("ATR");
break;
default :
settab("SPP");
break;
}
if (codice && *codice)
{
const int err = read(codice);
#ifdef DBG
if (err != NOERR)
switch (tipo)
{
case RIGA_SPESEDOC :
error_box("Spesa %s assente", codice);
break;
case RIGA_PRESTAZIONI :
error_box("Prestazione %s assente", codice);
break;
case RIGA_RISORSE :
error_box("Risorsa %s assente", codice);
break;
case RIGA_ATTREZZATURE :
error_box("Attrezzatura %s assente", codice);
break;
default :
error_box("Spesa %s assente", codice);
break;
}
#endif
}
}
TSpesa_prest::TSpesa_prest(const TRectype& rec)
: TRectype(rec)
{
}
char TSpesa_prest::genere() const
{
const TString & tipo = get("COD");
if (tipo == "SPP")
return RIGA_SPESEDOC;
else
if (tipo == "PRS")
return RIGA_PRESTAZIONI;
else
if (tipo == "RSS")
return RIGA_RISORSE;
else
if (tipo == "ATR")
return RIGA_ATTREZZATURE;
return ' ';
}
int TSpesa_prest::read(const char* codice)
{
const TString8 cod = get("COD");
*this = cache().get(cod, codice);
return empty() ? _iskeynotfound : NOERR;
}
const TString& TSpesa_prest::cod_iva() const
{
// La parte seguente di s3 e' utilizzata dalle atrezzature per altri campi
TString& tmp = get_tmp_string();
tmp = get("S3").left(4);
tmp.trim();
return tmp;
}
real TSpesa_prest::prezzo() const
{
real r = get("R10"); // Prezzo con tanti decimali
if (r.is_zero())
r = get_real("R0"); // Prezzo con pochi decimali
return r;
}
bool is_real_discount(const TString& exp)
{
if (exp.blank())
return false;
TString80 good;
real perc;
return scontoexpr2perc(exp, false , good, perc) && perc != UNO;
}
bool scontoexpr2perc(const char * exp, bool signal , TString & goodexp, real & val_perc )
{
bool valid = true;
goodexp.cut(0);
// Elimina gli spazi molesti
// work.strip_spaces( );
val_perc = 1.0;
if (exp && *exp)
{
TString80 num;
bool dec = false; // Flag che indica se si attende l'inizio di un numero
bool startnum = true; // Flag che indica se siamo all'inizio di un numero
int errorchar = ' ';
// Flag che indica se sono nella parte decimale di un numero
for (const char * s = exp; *s && errorchar == ' '; s++)
{
const char c = *s;
switch(c)
{
case '+':
case '-':
// Se ero in in numero ...
if( !startnum )
{
// Aggiunge il numero alla sequenza
real newval( num );
val_perc *= ( CENTO - newval ) / CENTO;
goodexp << num;
}
// Inizia il nuovo numero
num = (c == '-') ? "-" : "+";
startnum = true;
dec = false;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
num << c;
startnum = false;
break;
case '.':
case ',':
if(!dec)
{
if( startnum )
num << '0'; // Se occorreva un numero ci metto lo 0
num << '.'; // Interpreto la virgola come punto
dec = true;
startnum = true;
}
else
errorchar = c; // Se siamo gi` nella parte decimale segnala un errore
break;
case ' ':
break;
default:
errorchar = c;
break;
}
}
// Controlla la validita`
valid = errorchar == ' ';
if (valid)
{
// Aggiunge l'ultimo numero preso
real lastval( num );
val_perc *= ( CENTO - lastval ) / CENTO;
goodexp << num; // Assegna la nuova espressione formattata bene
}
else
{
if (signal) // Se richiesto segnala l'errore
warning_box( "Espressione di sconto non valida. Errore sul carattere %c.", errorchar);
val_perc = UNO; // Azzera la sequenza di percentuali
goodexp = "";
}
}
return valid;
}
real prezzo_scontato(const real& prezzo, const TString& sconto)
{
if (sconto.full())
{
TString80 exp;
real val_sconto;
if (scontoexpr2perc(sconto, false , exp, val_sconto) && val_sconto != UNO)
return prezzo * val_sconto;
}
return prezzo;
}