1207 lines
31 KiB
C++
Executable File
1207 lines
31 KiB
C++
Executable File
#include <progind.h>
|
|
#include <tabutil.h>
|
|
#include <utility.h>
|
|
#include <defmask.h>
|
|
|
|
#include "cg2100.h"
|
|
#include "cg2102.h"
|
|
|
|
|
|
// Certified 100%
|
|
inline TPrimanota_application& app()
|
|
{ return (TPrimanota_application&)*MainApp(); }
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Funzioni di decodifica/calcolo
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// Determina il tipo IVA da causale+anno
|
|
// Certified 100%
|
|
TipoIVA TPrimanota_application::cau2IVA(const char* causale, int annoiva)
|
|
{
|
|
TipoIVA i = iva_errata;
|
|
|
|
if (*causale > ' ')
|
|
{
|
|
TCausale c;
|
|
if (c.read(causale, annoiva))
|
|
i = c.iva();
|
|
else
|
|
error_box("Causale errata: '%s'", causale);
|
|
} else i = nessuna_iva;
|
|
|
|
return i;
|
|
}
|
|
|
|
// Calcolo della percentuale di un dato codice IVA
|
|
// Certified 99%
|
|
const real& TPrimanota_application::cod2IVA(const TMask& m)
|
|
{
|
|
static TString16 _codiva;
|
|
static real _percent;
|
|
|
|
const TString& codiva = m.get(102);
|
|
if (_codiva != codiva)
|
|
{
|
|
_codiva = codiva;
|
|
TCodiceIVA c(_codiva);
|
|
_percent = c.percentuale();
|
|
}
|
|
|
|
return _percent;
|
|
}
|
|
|
|
real TPrimanota_application::scorpora(real& imponibile, const real& percent)
|
|
{
|
|
real imposta = abs(imponibile) * percent / (percent + 100.0); imposta.ceil();
|
|
if (imponibile.sign() < 0) imposta = -imposta;
|
|
imponibile -= imposta;
|
|
return imposta;
|
|
}
|
|
|
|
real TPrimanota_application::totale_documento()
|
|
{
|
|
const TMask& m = mask();
|
|
|
|
const bool swapt = test_swap(FALSE); // Totale invertito ?
|
|
const bool swaps = test_swap(TRUE); // Ritenute sociali invertite ?
|
|
|
|
real tot(m.get(F_TOTALE));
|
|
tot += real(m.get(F_RITFIS));
|
|
|
|
real ritsoc(m.get(F_RITSOC));
|
|
if (swapt ^ swaps)
|
|
ritsoc = -ritsoc;
|
|
|
|
tot += ritsoc;
|
|
return tot;
|
|
}
|
|
|
|
// Determina se un codice sospeso o no
|
|
// Certified 50%
|
|
bool TPrimanota_application::suspended_handler(TMask_field& f, KEY k)
|
|
{
|
|
if (f.to_check(k))
|
|
{
|
|
CHECKD(f.is_edit(), "Can't check suspension of a non edit-field ", f.dlg());
|
|
const TEdit_field& c = (const TEdit_field&)f;
|
|
const TBrowse* b = c.browse();
|
|
CHECKD(b, "Can't check suspension of a edit-field without a USE ", f.dlg());
|
|
const TLocalisamfile* i = b->cursor()->file();
|
|
|
|
const char* sf = i->tab() ? "B2" : "SOSPESO";
|
|
const bool suspended = i->get_bool(sf);
|
|
if (suspended)
|
|
{
|
|
sf = f.get();
|
|
return f.error_box("Il codice '%s' e' sospeso e non puo' essere utilizzato", sf);
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// Determina se un codice detrazione e' di tipo detraibile o no
|
|
// Certified 70%
|
|
bool TPrimanota_application::detraibile(int tipodet)
|
|
{
|
|
if (tipodet)
|
|
return FALSE;
|
|
if (app().iva() != iva_acquisti)
|
|
return TRUE;
|
|
|
|
TString16 chiave;
|
|
chiave << app().mask().get(F_ANNOIVA) << app().causale().reg().attivita();
|
|
|
|
TTable pla("PLA");
|
|
pla.put("CODTAB", chiave);
|
|
const int err = pla.read();
|
|
real prorata;
|
|
if (err == NOERR)
|
|
prorata = pla.get_real("R8");
|
|
|
|
return prorata != 100.0;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Funzioni di ricerca
|
|
///////////////////////////////////////////////////////////
|
|
|
|
int TPrimanota_application::type2pos(char tipo)
|
|
{
|
|
TSheet_field& cg = app().cgs();
|
|
for (int i = 0; i < cg.items(); i++)
|
|
{
|
|
TToken_string& s = cg.row(i);
|
|
if (s[s.len()-1] == tipo)
|
|
return i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
int TPrimanota_application::bill2pos(const TConto& conto, char tipo)
|
|
{
|
|
TSheet_field& cg = app().cgs();
|
|
for (int i = 0; i < cg.items(); i++)
|
|
{
|
|
TToken_string& s = cg.row(i);
|
|
if (s[s.len()-1] == tipo)
|
|
{
|
|
const TConto c(s, 3, 0x0);
|
|
if (c == conto)
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
int TPrimanota_application::bill2contr(const TConto& conto, char sezione) const
|
|
{
|
|
const TArray& rows = cgs().rows_array();
|
|
for (int i = 0; i < rows.items(); i++)
|
|
{
|
|
TToken_string& row = (TToken_string&)rows[i];
|
|
const char sez = row.get(0)[0] > ' ' ? 'D' : 'A';
|
|
if (sez == sezione) // Devo cercare sezione contraria
|
|
continue;
|
|
const TConto c(row, 3, 0x0);
|
|
if (conto == c)
|
|
return i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
// Controlla se un conto e' usato nelle righe IVA
|
|
int TPrimanota_application::bill_used(const TConto& conto) const
|
|
{
|
|
int users = 0;
|
|
|
|
const TArray& rows = ivas().rows_array();
|
|
for (int i = 0; i < rows.items(); i++)
|
|
{
|
|
TToken_string& row = (TToken_string&)rows[i];
|
|
if (!row.empty_items())
|
|
{
|
|
const TConto c(row, 6, 0x0);
|
|
if (conto == c) users++;
|
|
}
|
|
}
|
|
|
|
return users;
|
|
}
|
|
|
|
|
|
int TPrimanota_application::det_used(char det) const
|
|
{
|
|
int users = 0;
|
|
|
|
const bool detraib = det == 'D';
|
|
const TArray& rows = ivas().rows_array();
|
|
for (int i = 0; i < rows.items(); i++)
|
|
{
|
|
TToken_string& row = (TToken_string&)rows[i];
|
|
if (!row.empty_items())
|
|
{
|
|
const bool d = detraibile(row.get_int(4));
|
|
if (detraib == d) users++;
|
|
}
|
|
}
|
|
|
|
return users;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Gestione sheet CG
|
|
///////////////////////////////////////////////////////////
|
|
|
|
TMask& TPrimanota_application::mask() const
|
|
{
|
|
TipoIVA i = app().iva();
|
|
return *_msk[i == nessuna_iva ? 1 : 2];
|
|
}
|
|
|
|
|
|
TSheet_field& TPrimanota_application::cgs() const
|
|
{
|
|
TSheet_field& s = (TSheet_field&)mask().field(F_SHEETCG);
|
|
return s;
|
|
}
|
|
|
|
|
|
// Certified 99%
|
|
// Scrive l'importo imp nella opportuna sezione della riga n
|
|
void TPrimanota_application::set_cgs_imp(int n, const TImporto& imp)
|
|
{
|
|
imp.add_to(cgs().row(n));
|
|
cgs().force_update(n);
|
|
}
|
|
|
|
// Legge l'importo della riga n e lo ritorna col segno dovuto
|
|
// Certified 99%
|
|
TImporto TPrimanota_application::get_cgs_imp(int n)
|
|
{
|
|
TImporto importo;
|
|
importo = cgs().row(n);
|
|
return importo;
|
|
}
|
|
|
|
// Certified 90%
|
|
void TPrimanota_application::add_cgs_imp(int n, const TImporto& imp)
|
|
{
|
|
TImporto tot(get_cgs_imp(n));
|
|
tot.set(imp.sezione(), tot.valore() + imp.valore());
|
|
set_cgs_imp(n, tot);
|
|
}
|
|
|
|
// Certified 90%
|
|
void TPrimanota_application::sub_cgs_imp(int n, const real& imp)
|
|
{
|
|
TImporto tot(get_cgs_imp(n));
|
|
tot.set(tot.sezione(), tot.valore() - imp);
|
|
set_cgs_imp(n, tot);
|
|
}
|
|
|
|
|
|
TImporto TPrimanota_application::real2imp(const real& r, char row_type)
|
|
{
|
|
bool dare;
|
|
if (row_type == 'S')
|
|
{
|
|
dare = causale().sezione_ritsoc() == 'D';
|
|
}
|
|
else
|
|
{
|
|
dare = causale().sezione_clifo() == 'D';
|
|
if (row_type != 'T' && row_type != 'F') dare = !dare;
|
|
}
|
|
|
|
TImporto importo(dare ? 'D' : 'A', r);
|
|
return importo;
|
|
}
|
|
|
|
// Disabilita le celle della riga contabile n in base al suo tipo
|
|
void TPrimanota_application::disable_cgs_cells(int n, char tipo)
|
|
{
|
|
int last;
|
|
switch(tipo)
|
|
{
|
|
case 'F': // Ritenute Fiscali
|
|
case 'S': // Ritenute Sociali
|
|
case 'D': // IVA Detraibile
|
|
case 'N':
|
|
last = 3; // IVA Non detraibile
|
|
break;
|
|
case 'T': // Totale documento
|
|
case 'I':
|
|
last = 7; // Imponibile
|
|
break;
|
|
default :
|
|
last = 0; // Solo contabile
|
|
break;
|
|
}
|
|
|
|
TSheet_field& cg = cgs();
|
|
for (int i = 0; i < last; i++)
|
|
cg.disable_cell(n, i);
|
|
|
|
if (tipo == 'T')
|
|
{
|
|
cg.enable_cell(n, 3);
|
|
cg.enable_cell(n, 4);
|
|
}
|
|
}
|
|
|
|
|
|
int TPrimanota_application::set_cgs_row(int n, const TImporto& imp,
|
|
TConto& conto, const char* desc,
|
|
char tipo)
|
|
{
|
|
TSheet_field& cg = cgs();
|
|
if (n < 0) n = cg.first_empty();
|
|
TToken_string& row = cg.row(n);
|
|
row = "";
|
|
imp.add_to(row);
|
|
row.add(conto.string(0x3));
|
|
row.add("");
|
|
row.add(desc);
|
|
|
|
int pos = 0;
|
|
if (tipo == 'I' && (pos = type2pos('T')) >= 0)
|
|
{
|
|
TConto contro(cg.row(pos), 2, 0x3);
|
|
row.add(contro.string(0x3));
|
|
}
|
|
else
|
|
{
|
|
row.add(" | | | | "); // Contropartita
|
|
}
|
|
row << '|' << tipo;
|
|
|
|
disable_cgs_cells(n, tipo);
|
|
if (tipo == ' ')
|
|
cg.disable_cell(n, imp.sezione() == 'D' ? 1 : 0);
|
|
|
|
cg.force_update(n);
|
|
|
|
return n;
|
|
}
|
|
|
|
|
|
HIDDEN int compare_rows(const TObject** o1, const TObject** o2)
|
|
{
|
|
// Totale, Rit.Fisc., Rit.Soc., da riga IVA, riga contabile, IVA detr., IVA non detr.
|
|
static char* sort_order = "TFSI DN";
|
|
|
|
const TToken_string* r1 = (const TToken_string*)*o1;
|
|
const TToken_string* r2 = (const TToken_string*)*o2;
|
|
const char c1 = r1->right(1)[0];
|
|
const char c2 = r2->right(1)[0];
|
|
return int(strchr(sort_order, c1) - strchr(sort_order, c2));
|
|
}
|
|
|
|
|
|
void TPrimanota_application::cgs_pack()
|
|
{
|
|
TArray& rows = cgs().rows_array();
|
|
|
|
const int max = rows.items();
|
|
for (int i = 0; i < max; i++)
|
|
{
|
|
TToken_string& r = (TToken_string&)rows[i];
|
|
bool del = FALSE;
|
|
if (r.empty_items()) // Remove all empty strings
|
|
del = TRUE;
|
|
else
|
|
{
|
|
const TImporto& imp = get_cgs_imp(i);
|
|
if (imp.valore() == ZERO)
|
|
del = TRUE;
|
|
}
|
|
if (del)
|
|
rows.destroy(i, FALSE);
|
|
}
|
|
|
|
rows.sort(compare_rows); // Pack and sort array
|
|
}
|
|
|
|
|
|
real TPrimanota_application::calcola_saldo() const
|
|
{
|
|
TArray& rows = cgs().rows_array();
|
|
const int max = rows.items();
|
|
|
|
real tdare, tavere;
|
|
for (int i = 0; i < max; i++)
|
|
{
|
|
TToken_string& r = (TToken_string&)rows[i];
|
|
tdare += real(r.get(0));
|
|
tavere += real(r.get());
|
|
}
|
|
|
|
real sbilancio = abs(tdare)-abs(tavere);
|
|
switch (sbilancio.sign())
|
|
{
|
|
case 1:
|
|
mask().set(F_DARE, (tdare-tavere).string());
|
|
mask().reset(F_AVERE);
|
|
break;
|
|
case -1:
|
|
mask().reset(F_DARE);
|
|
mask().set(F_AVERE, (tavere-tdare).string());
|
|
break;
|
|
default:
|
|
mask().reset(F_DARE);
|
|
mask().reset(F_AVERE);
|
|
break;
|
|
}
|
|
|
|
return sbilancio;
|
|
}
|
|
|
|
|
|
// Handler dello sheet di contabilita'
|
|
// Certified 90%
|
|
bool TPrimanota_application::cg_handler(TMask_field& f, KEY k)
|
|
{
|
|
if (k == K_ENTER)
|
|
{
|
|
TSheet_field& cg = app().cgs();
|
|
real saldo = app().calcola_saldo();
|
|
if (saldo != ZERO)
|
|
{
|
|
const char* ss = saldo.string(".");
|
|
return f.error_box("Il movimento e' sbilanciato di %s lire.", ss);
|
|
}
|
|
else
|
|
if (app().get_cgs_imp(0).valore() == ZERO)
|
|
return f.error_box("Il movimento non ha una prima riga contabile valida!");
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
bool TPrimanota_application::cg_notify(int r, KEY k)
|
|
{
|
|
TSheet_field& cg = app().cgs();
|
|
TToken_string& row = cg.row(r);
|
|
const char tipo = row.empty() ? ' ' : row.right(1)[0];
|
|
|
|
switch(k)
|
|
{
|
|
case K_SPACE:
|
|
cg.sheet_mask().enable(DLG_DELREC, tipo == ' ');
|
|
break;
|
|
case K_ENTER:
|
|
if (r == 0 && app().iva() == nessuna_iva && cg.row(1).empty_items())
|
|
{
|
|
TImporto i; i = row; i.swap_section();
|
|
TConto contro(row, 9, 0x3);
|
|
app().set_cgs_row(1, i, contro, "", ' ');
|
|
TConto conto(cg.row(1), 2, 0x3);
|
|
conto.add_to(cg.row(1), 2, 0x3);
|
|
}
|
|
app().calcola_saldo();
|
|
break;
|
|
case K_DEL:
|
|
if (tipo != ' ')
|
|
return error_box("La riga %d non puo' essere cancellata", r+1);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
bool TPrimanota_application::descr_handler(TMask_field& f, KEY k)
|
|
{
|
|
if (k == K_ENTER && f.get().empty())
|
|
{
|
|
if (f.mask().get(F_CODCAUS).empty())
|
|
return error_box("Descrizione documento necessaria in mancanza della causale");
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// Handler per le colonne 'Dare' e 'Avere' dello sheet contabile.
|
|
// Scrivendo qualcosa in dare (101) cancella l'importo in avere (102) e viceversa
|
|
bool TPrimanota_application::dareavere_handler(TMask_field& f, KEY k)
|
|
{
|
|
if (k == K_TAB && f.focusdirty() && !f.get().empty())
|
|
{
|
|
const int id = 203-f.dlg(); // Calcola id del campo da resettare
|
|
f.mask().reset(id);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Gestione sheet IVA
|
|
///////////////////////////////////////////////////////////
|
|
|
|
TSheet_field& TPrimanota_application::ivas() const
|
|
{
|
|
TSheet_field& s = (TSheet_field&)_msk[2]->field(F_SHEETIVA);
|
|
return s;
|
|
}
|
|
|
|
|
|
void TPrimanota_application::set_ivas_row(int nriga, const char* codiva, TConto& tc,
|
|
const char* desc)
|
|
{
|
|
TToken_string& riga = ivas().row(nriga);
|
|
riga = " "; // Importo
|
|
riga.add (codiva); // codiva
|
|
riga.add (" | | "); // Det - Imposta - C/R
|
|
riga.add(tc.string(0x3)); // Conto
|
|
riga.add(desc); // Descrizione
|
|
}
|
|
|
|
|
|
bool TPrimanota_application::imponibile_handler(TMask_field& f, KEY key)
|
|
{
|
|
if (key == K_TAB && f.dirty())
|
|
{
|
|
TString16 iva(f.mask().get(102));
|
|
if (iva.empty())
|
|
{
|
|
iva = app().mask().get(F_CODIVA);
|
|
f.mask().set(102, iva);
|
|
}
|
|
if (iva.not_empty()) // Se c'e' il codice IVA
|
|
{
|
|
const real& percent = cod2IVA(f.mask());
|
|
const real imponibile(f.get());
|
|
real imposta = abs(imponibile) * percent / 100.0; imposta.ceil();
|
|
if (imponibile.sign() < 0) imposta = -imposta;
|
|
f.mask().set(104, imposta.string());
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
bool TPrimanota_application::codiva_handler(TMask_field& f, KEY key)
|
|
{
|
|
if (key == K_TAB && f.dirty())
|
|
{
|
|
TMask_field& i = f.mask().field(101);
|
|
i.set_dirty();
|
|
return imponibile_handler(i, key);
|
|
} else
|
|
if (key == K_ENTER)
|
|
{
|
|
if (f.get().empty() && f.mask().get(101).not_empty())
|
|
return f.error_box("Codice IVA obbligatorio");
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
bool TPrimanota_application::imposta_handler(TMask_field& f, KEY key)
|
|
{
|
|
if (key == K_ENTER)
|
|
{
|
|
const real imponibile(f.mask().get(101));
|
|
const real& percent = cod2IVA(f.mask());
|
|
real imposta = abs(imponibile) * percent / 100.0;
|
|
imposta.ceil();
|
|
if (imponibile < ZERO) imposta = -imposta;
|
|
|
|
const real val(f.get());
|
|
if (val != imposta)
|
|
{
|
|
if (val != 0.0 || !app().causale().corrispettivi())
|
|
{
|
|
const TString16 wrong(val.string("."));
|
|
const TString16 right(imposta.string("."));
|
|
f.warning_box("Imposta di '%s' errata: dovrebbe essere '%s'",
|
|
(const char*)wrong, (const char*)right);
|
|
}
|
|
}
|
|
} else
|
|
if (key == K_F8 && f.get().empty())
|
|
{
|
|
real imponibile(f.mask().get(101));
|
|
const real& percent = cod2IVA(f.mask());
|
|
const real imposta = scorpora(imponibile, percent);
|
|
f.mask().set(101, imponibile.string());
|
|
f.set(imposta.string());
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
real TPrimanota_application::calcola_imp() const
|
|
{
|
|
TArray& rows = ivas().rows_array();
|
|
const int max = rows.items();
|
|
|
|
real imponibili, imposte;
|
|
for (int r = 0; r < max; r++)
|
|
{
|
|
TToken_string& row = (TToken_string&)rows[r];
|
|
imponibili += real(row.get(0));
|
|
imposte += real(row.get(3));
|
|
}
|
|
|
|
mask().set(F_IMPONIBILI, imponibili.string());
|
|
mask().set(F_IMPOSTE, imposte.string());
|
|
|
|
return imponibili+imposte;
|
|
}
|
|
|
|
// Certified 50%
|
|
bool TPrimanota_application::iva_notify(int r, KEY k)
|
|
{
|
|
static int oldpos,oldposiva;
|
|
static real oldimp, oldiva;
|
|
|
|
TSheet_field& iva = app().ivas();
|
|
TToken_string& row = iva.row(r);
|
|
|
|
if (k == K_SPACE)
|
|
{
|
|
oldimp = real(row.get(0)); // Imponibile 0
|
|
oldiva = real(row.get(3)); // Imposta 3
|
|
|
|
const char tipod = detraibile(row.get_int()) ? 'D' : 'N';
|
|
oldposiva = type2pos(tipod); // Tipodet 4
|
|
if (oldposiva < 0 && oldiva != ZERO)
|
|
{
|
|
TConto c; app().causale().bill(tipod == 'D' ? 3 : 4, c);
|
|
oldposiva = app().set_cgs_row(-1, app().real2imp(ZERO, 'I'), c, "", tipod);
|
|
}
|
|
|
|
TConto oldconto(row, 5, 0x1); // t/g/c/s 5 6 7 8
|
|
oldpos = bill2pos(oldconto, 'I');
|
|
if (oldpos < 0 && oldconto.ok())
|
|
oldpos = app().set_cgs_row(-1, app().real2imp(ZERO, 'I'), oldconto, "", 'I');
|
|
}
|
|
if (k == K_DEL)
|
|
{
|
|
row.add("0", 0); // Azzera imponibile
|
|
row.add("0", 3); // Azzera imposta
|
|
k = K_ENTER; // Elegante o Sporco trucco (dipende dai gusti!)
|
|
}
|
|
if (k == K_ENTER)
|
|
{
|
|
if (oldpos >= 0) // Il conto esisteva anche prima
|
|
{
|
|
app().sub_cgs_imp(oldpos, oldimp);
|
|
}
|
|
if (oldposiva >= 0) // Il conto IVA esisteva anche prima
|
|
{
|
|
app().sub_cgs_imp(oldposiva, oldiva);
|
|
}
|
|
|
|
// Aggiorna conto sulla riga contabile
|
|
real imp(row.get(0)); // Imponibile
|
|
TConto conto(row, 5, 0x3);
|
|
const int newpos = bill2pos(conto, 'I');
|
|
|
|
if (newpos < 0)
|
|
{
|
|
const TImporto val(app().real2imp(imp, 'I'));
|
|
if (val.valore() != ZERO)
|
|
app().set_cgs_row(-1, val, conto, "", 'I');
|
|
}
|
|
else
|
|
{
|
|
const TImporto val(app().real2imp(imp, 'I'));
|
|
app().add_cgs_imp(newpos, val);
|
|
}
|
|
oldimp = imp;
|
|
oldpos = newpos;
|
|
|
|
// Aggiorna conto IVA sulla riga contabile
|
|
|
|
imp = real(row.get(3)); // Imposta
|
|
const bool detrarre = detraibile(row.get_int()); // Determina se IVA detraibile
|
|
app().causale().bill(detrarre ? 3 : 4, conto);
|
|
const char tipod = detrarre ? 'D' : 'N';
|
|
const int newposiva = type2pos(tipod);
|
|
|
|
if (newposiva < 0)
|
|
{
|
|
const TImporto val(app().real2imp(imp, 'I'));
|
|
if (val.valore() != ZERO)
|
|
app().set_cgs_row(-1, val, conto, "", tipod);
|
|
}
|
|
else
|
|
{
|
|
const TImporto val(app().real2imp(imp, 'I'));
|
|
app().add_cgs_imp(newposiva, val);
|
|
}
|
|
oldiva = imp;
|
|
oldposiva = newposiva;
|
|
|
|
app().calcola_imp();
|
|
app().calcola_saldo();
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// Handler dello sheet di contabilita'
|
|
// Certified 90%
|
|
bool TPrimanota_application::iva_handler(TMask_field& f, KEY k)
|
|
{
|
|
if (k != K_ENTER) return TRUE;
|
|
|
|
const real imp = app().calcola_imp();
|
|
const real tot = app().totale_documento();
|
|
|
|
if (imp != tot)
|
|
{
|
|
TString16 t(tot.string("."));
|
|
TString16 i(imp.string("."));
|
|
return error_box("La somma del totale documento e delle ritenute (%s) e' diverso dalla "
|
|
"somma degli imponibili e delle imposte (%s)", (const char*)t, (const char*)i);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Handlers dei campi della testata
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
|
// Handler of the F_NUMREG field on the query mask
|
|
// Certified 90%
|
|
bool TPrimanota_application::num_handler(TMask_field& f, KEY key)
|
|
{
|
|
if (!f.mask().is_running()) return TRUE;
|
|
|
|
if (key == K_TAB && f.get().not_empty())
|
|
{
|
|
if (app().find(1))
|
|
dispatch_e_char(f.parent(), K_AUTO_ENTER);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// Handler of the F_CODCAUS field on the query mask
|
|
// Certified 99%
|
|
bool TPrimanota_application::caus_query_handler(TMask_field& f, KEY key)
|
|
{
|
|
if (!f.mask().is_running()) return TRUE;
|
|
|
|
if (key == K_TAB && f.focusdirty())
|
|
{
|
|
const int ann = f.mask().get_int(F_ANNOIVA);
|
|
const char* cau = f.get();
|
|
|
|
const TipoIVA i = cau2IVA(cau, ann); // Cerca causale e suo tipo
|
|
if (i != iva_errata)
|
|
{
|
|
const bool ok = suspended_handler(f, key); // Controlla sospensione
|
|
if (ok)
|
|
f.mask().stop_run(K_INS); // Entra in modo inserimento
|
|
}
|
|
else return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// Handler of the F_CODCAUS field on the modify mask
|
|
// Certified 99%
|
|
bool TPrimanota_application::caus_modify_handler(TMask_field& f, KEY key)
|
|
{
|
|
if (f.to_check(key))
|
|
{
|
|
bool ok = suspended_handler(f, key);
|
|
if (!ok) return FALSE;
|
|
|
|
const int ann = f.mask().get_int(F_ANNOIVA);
|
|
const char* cau = f.get();
|
|
TCausale c(cau, ann);
|
|
if (!c.ok()) return FALSE;
|
|
|
|
|
|
ok = app().causale().similar(c);
|
|
if (!ok)
|
|
{
|
|
f.error_box("Causale incongruente con quella precedentemente inserita");
|
|
return FALSE;
|
|
}
|
|
app().read_caus(cau, ann);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// Handler of the F_DATAREG field
|
|
// Certified 70%
|
|
bool TPrimanota_application::datareg_handler(TMask_field& f, KEY key)
|
|
{
|
|
bool ok = TRUE;
|
|
|
|
if ((key == K_TAB && f.focusdirty()) || key == K_ENTER)
|
|
{
|
|
const TDate dr(f.get()); // Data dell'operazione
|
|
if (dr > TDate(TODAY))
|
|
return f.error_box("La data dell'operazione e' superiore quella di sistema");
|
|
|
|
TMask& m = f.mask();
|
|
|
|
const int ae = date2esc(dr); // Anno esercizio
|
|
if (ae == 0)
|
|
return f.error_box("La data dell'operazione non appartiene a nessun esercizio");
|
|
|
|
if (m.query_mode() || app().giornale().year() != ae)
|
|
ok = app().giornale().read(ae);
|
|
else
|
|
ok = TRUE;
|
|
|
|
if (!ok)
|
|
return f.error_box("Non esiste il libro giornale dell'esercizio %d", ae);
|
|
|
|
if (f.dirty() || f.mask().query_mode())
|
|
{
|
|
const TLibro_giornale& gio = app().giornale();
|
|
const TDate ljp(gio.global_last_print());
|
|
if (dr <= ljp)
|
|
return f.error_box("La data dell'operazione e' antecedente alla data\n"
|
|
"dell'ultima stampa del libro giornale: %s", ljp.string());
|
|
if (dr < gio.last_reg())
|
|
warning_box("La data dell'operazione e' antecedente al %s, ultima registrazione\n"
|
|
"sul libro giornale del %d",
|
|
gio.last_reg().string(), ae);
|
|
|
|
if (m.query_mode())
|
|
app().read_caus(m.get(F_CODCAUS), dr.year());
|
|
|
|
TRegistro& reg = app().causale().reg();
|
|
const TString16 codreg(reg.name());
|
|
if (codreg.not_empty())
|
|
{
|
|
|
|
if (reg.year() != dr.year())
|
|
{
|
|
const bool ok = reg.read(codreg, dr.year());
|
|
if (!ok) return FALSE;
|
|
}
|
|
|
|
if (dr <= reg.last_print())
|
|
return error_box("La data dell'operazione e' antecedente al %s, ultima\n"
|
|
"data di stampa del registro '%s' dell'anno %d",
|
|
reg.last_print().string(), (const char*)codreg, dr.year());
|
|
if (dr < reg.last_reg())
|
|
warning_box("La data dell'operazione e' antecedente al %s, ultima registrazione\n"
|
|
"sul registro '%s' dell'anno %d",
|
|
reg.last_reg().string(), (const char*)codreg, dr.year());
|
|
}
|
|
}
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
// Handler of the F_DATACOMP field on the modify mask
|
|
// Certified 90%
|
|
bool TPrimanota_application::datacomp_handler(TMask_field& f, KEY key)
|
|
{
|
|
if (!f.to_check(key, TRUE))
|
|
return TRUE;
|
|
|
|
const TDate dc(f.get()); // Data di competenza
|
|
const int ae = date2esc(dc); // Esercizio corrispondente
|
|
TMask& m = f.mask();
|
|
|
|
if (ae)
|
|
{
|
|
if (f.dlg() == F_DATACOMP)
|
|
m.set(F_ANNOES, ae);
|
|
|
|
const TDate dr(m.get(F_DATAREG)); // Data operazione
|
|
int pr; // Esercizio precedente
|
|
const int ar = date2esc(dr, &pr); // Esercizio in corso
|
|
if (ae != ar && ae != pr)
|
|
{
|
|
TString80 e("La data deve appartenere all'esercizio ");
|
|
e << ar;
|
|
if (pr > 0) e << " o al " << pr;
|
|
return f.error_box(e);
|
|
}
|
|
}
|
|
else
|
|
return f.error_box("La data non appartiene a nessun esercizio");
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// Handler of the F_DATA74TER field on the modify mask
|
|
// Certified 90%
|
|
bool TPrimanota_application::data74ter_handler(TMask_field& f, KEY key)
|
|
{
|
|
if (!f.to_check(key)) return TRUE;
|
|
bool ok = datacomp_handler(f, key);
|
|
if (ok)
|
|
{
|
|
const TDate d74(f.get());
|
|
const TLibro_giornale& g = app().giornale();
|
|
if (d74 < g.last_print())
|
|
{
|
|
ok = f.error_box("La data per il 74/ter e' antecedente alla data di stampa "
|
|
"del libro giornale dell'esercizio %d", g.year());
|
|
}
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
// Handler of the F_CODREG field on the modify mask
|
|
// Certified 99%
|
|
bool TPrimanota_application::reg_handler(TMask_field& f, KEY key)
|
|
{
|
|
if (f.to_check(key, TRUE))
|
|
{
|
|
// if (!suspended_handler(f, key)) return FALSE;
|
|
|
|
const int ai = f.mask().get_int(F_ANNOIVA);
|
|
const char* r = f.get();
|
|
TRegistro reg(r, ai);
|
|
|
|
const TipoIVA i = reg.iva();
|
|
if (i == iva_errata)
|
|
return f.error_box("Tipo registro errato");
|
|
|
|
if (reg.iva() != app().iva())
|
|
{
|
|
const TString16 i1(iva2name(reg.iva()));
|
|
const TString16 i2(iva2name(app().iva()));
|
|
return f.error_box("Tipo registro (%s) incongruente col tipo di registrazione (%s)",
|
|
(const char*)i1, (const char*)i2);
|
|
}
|
|
|
|
const bool av = reg.agenzia_viaggi();
|
|
f.mask().show(F_DATA74TER, av);
|
|
if (!av) f.mask().reset(F_DATA74TER);
|
|
|
|
if (key == K_TAB)
|
|
app().causale().reg() = reg;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
bool TPrimanota_application::occas_code_handler(TMask_field& f, KEY key)
|
|
{
|
|
if (key == K_TAB)
|
|
{
|
|
const char* code = f.get();
|
|
if (*code)
|
|
{
|
|
TRelation occas(LF_OCCAS);
|
|
occas.lfile()->put("CFPI", code);
|
|
if (occas.read() == NOERR)
|
|
{
|
|
f.mask().autoload(&occas);
|
|
f.mask().send_key(K_TAB, O_COMUNE); // Forza decodifica comuni
|
|
f.mask().send_key(K_TAB, O_COMUNENAS);
|
|
}
|
|
}
|
|
} else
|
|
if (key == K_ENTER)
|
|
{
|
|
const TFixed_string codice(f.get());
|
|
if (codice.not_empty())
|
|
app().mask().set(app().iva() == iva_vendite ? F_PIVACLIENTE : F_PIVAFORNITORE, codice);
|
|
else
|
|
return f.error_box("Il codice e' obbligatorio");
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
bool TPrimanota_application::occas_handler(TMask_field& f, KEY key)
|
|
{
|
|
if (key == K_SPACE && f.mask().is_running())
|
|
{
|
|
TMask& om = app().occas_mask();
|
|
om.run();
|
|
f.set_focus();
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
// Crea o aggiorna la riga contabile col totale documento
|
|
// Certified 99%
|
|
void TPrimanota_application::add_cgs_tot(TMask& m)
|
|
{
|
|
// Lettura del conto dalla maschera
|
|
char tipo = m.get(F_CLIFO)[0];
|
|
int gruppo = m.get_int(F_GRUPPOCLIFO);
|
|
int conto = m.get_int(F_CONTOCLIFO);
|
|
long codice = m.get_long(tipo == 'C' ? F_CLIENTE : F_FORNITORE);
|
|
|
|
// Se l'utente non ha ancora specificato un conto lo prendo dalla prima riga della causale
|
|
if (conto == 0)
|
|
{
|
|
TConto bill; _causale.bill(1, bill);
|
|
gruppo = bill.gruppo(); m.set(F_GRUPPOCLIFO, gruppo);
|
|
conto = bill.conto(); m.set(F_CONTOCLIFO, conto);
|
|
}
|
|
|
|
if (tipo == 'C' && causale().corrispettivi())
|
|
tipo = ' ';
|
|
TConto c(gruppo, conto, codice, tipo);
|
|
real tot(m.get(F_TOTALE));
|
|
|
|
// Creazione/Aggiornamento riga totale
|
|
const int pos = type2pos('T');
|
|
set_cgs_row(pos, real2imp(tot, 'T'), c, "Totale documento", 'T');
|
|
calcola_saldo();
|
|
}
|
|
|
|
|
|
// Handler of the F_CLIENTE & F_FORNITORE field on the modify mask
|
|
// Certified 99%
|
|
bool TPrimanota_application::clifo_handler(TMask_field& f, KEY key)
|
|
{
|
|
if (!suspended_handler(f, key))
|
|
return FALSE;
|
|
|
|
if (key == K_TAB && f.focusdirty())
|
|
{
|
|
app().add_cgs_tot(f.mask());
|
|
TLocalisamfile clifo(LF_CLIFO);
|
|
const int alleg = clifo.get_int("ALLEG");
|
|
TEdit_field& upi = (TEdit_field&)f.mask().field(F_RIEPILOGO);
|
|
upi.check_type(alleg == 3 ? CHECK_REQUIRED : CHECK_NORMAL);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// Handler of the F_CODIVA
|
|
// Certified 99%
|
|
bool TPrimanota_application::main_codiva_handler(TMask_field& f, KEY key)
|
|
{
|
|
if (key == K_TAB && f.focusdirty() && f.get().not_empty())
|
|
{
|
|
TToken_string& row = app().ivas().row(0);
|
|
const real imp(row.get(0));
|
|
if (imp == ZERO)
|
|
{
|
|
iva_notify(0, K_SPACE);
|
|
|
|
const TCodiceIVA iva(f.get());
|
|
real tot = app().totale_documento();
|
|
|
|
real imposta;
|
|
if (!app().causale().corrispettivi())
|
|
imposta = app().scorpora(tot, iva.percentuale());
|
|
|
|
row.add(tot.string(), 0); // imponibile
|
|
row.add(iva.codice(), 1); // codice IVA
|
|
row.add(imposta.string(), 3); // imposta
|
|
|
|
TConto bill; // Conto della prima riga IVA
|
|
const TString& tipo = iva.tipo();
|
|
if (tipo.not_empty())
|
|
{
|
|
if (tipo == "ES") app().causale().bill(5, bill); else
|
|
if (tipo == "NI") app().causale().bill(6, bill); else
|
|
if (tipo == "NS") app().causale().bill(7, bill);
|
|
}
|
|
if (!bill.ok() && !app().causale().corrispettivi())
|
|
{
|
|
const TMask& m = f.mask();
|
|
bill.set(m.get_int(F_GRUPPORIC), m.get_int(F_CONTORIC), m.get_long(F_SOTTOCONTORIC));
|
|
}
|
|
if (!bill.ok())
|
|
app().causale().bill(2, bill);
|
|
row.add(bill.tipo(), 5);
|
|
row.add(bill.gruppo(), 6);
|
|
row.add(bill.conto(), 7);
|
|
row.add(bill.sottoconto(), 8);
|
|
row.add(bill.descrizione(), 9);
|
|
|
|
app().ivas().force_update(0);
|
|
iva_notify(0, K_ENTER);
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
// Handler of the F_TOTALE
|
|
// Certified 99%
|
|
bool TPrimanota_application::totale_handler(TMask_field& f, KEY key)
|
|
{
|
|
bool ok = TRUE;
|
|
if (key == K_TAB && f.focusdirty())
|
|
app().add_cgs_tot(f.mask());
|
|
|
|
if (key == K_ENTER && f.get().empty())
|
|
ok = f.yesno_box("Totale documento nullo: continuare ugualmente?");
|
|
return ok;
|
|
}
|
|
|
|
|
|
void TPrimanota_application::add_cgs_rit(bool fiscali)
|
|
{
|
|
const real imp(_msk[2]->get(fiscali ? F_RITFIS : F_RITSOC));
|
|
|
|
const char tipo = fiscali ? 'F' : 'S';
|
|
int pos = type2pos(tipo);
|
|
if (pos < 0)
|
|
{
|
|
const int riga = fiscali ? 8 : 9;
|
|
TConto conto; _causale.bill(riga, conto);
|
|
|
|
TString80 desc("Ritenute ");
|
|
desc << (fiscali ? "fiscali" : "sociali");
|
|
|
|
set_cgs_row(-1, real2imp(imp, tipo), conto, desc, tipo);
|
|
}
|
|
else
|
|
set_cgs_imp(pos, real2imp(imp, tipo));
|
|
}
|
|
|
|
|
|
// Handler of the F_RITFIS
|
|
// Certified 99%
|
|
bool TPrimanota_application::ritfis_handler(TMask_field& f, KEY key)
|
|
{
|
|
if (key == K_TAB && f.focusdirty())
|
|
app().add_cgs_rit(TRUE);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// Handler of F_RITSOC
|
|
// Certified 99%
|
|
bool TPrimanota_application::ritsoc_handler(TMask_field& f, KEY key)
|
|
{
|
|
if (key == K_TAB && f.focusdirty())
|
|
app().add_cgs_rit(FALSE);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// Handler of F_VISVAL
|
|
// Certified 90%
|
|
bool TPrimanota_application::visval_handler(TMask_field& f, KEY key)
|
|
{
|
|
if (key == K_SPACE)
|
|
{
|
|
TMask& m = f.mask();
|
|
const real e(f.get() == "X" ? m.get(F_CAMBIO) : "1");
|
|
m.set_exchange(e);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
bool TPrimanota_application::solaiva_handler(TMask_field& f, KEY key)
|
|
{
|
|
if (key == K_SPACE)
|
|
{
|
|
TMask& m = f.mask();
|
|
const bool anchecg = !m.get_bool(F_SOLAIVA);
|
|
|
|
app().cgs().show(anchecg);
|
|
|
|
if (m.is_running() && anchecg)
|
|
{
|
|
TSheet_field& iva = app().ivas();
|
|
const int righe = iva.items();
|
|
TProgind pi(righe, "Generazione righe contabilita'", FALSE, TRUE, 16);
|
|
|
|
app().cgs().reset();
|
|
app().add_cgs_tot(m);
|
|
if (m.get(F_RITFIS).not_empty()) app().add_cgs_rit(TRUE);
|
|
if (m.get(F_RITSOC).not_empty()) app().add_cgs_rit(FALSE);
|
|
|
|
TToken_string oldrow(128);
|
|
for (int i = 0; i < righe; i++)
|
|
{
|
|
TToken_string& r = iva.row(i);
|
|
if (!r.empty_items())
|
|
{
|
|
oldrow = r;
|
|
r = "";
|
|
iva_notify(i, K_SPACE);
|
|
r = oldrow;
|
|
iva_notify(i, K_ENTER);
|
|
}
|
|
pi.setstatus(i+1);
|
|
}
|
|
app().fill_sheet(m);
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|