Files correlati : cg0.exe cg0500a.msk cg2.exe cg2100s.msk Ricompilazione Demo : [ ] Commento : CM20044 Causale senza tipo documento e con tipo movimento fattura. Mi propone la pagina delle scandenze completamente vuota pur avendo indicato il codice pagamento in testata. La seguente pagina riconosce il pagamento solo se clicco sul botone di reset. CM20045 Causale senza tipo documento e con tipo movimento nota di credito. Mi lascia registrare in prima nota senza portarmi nella gestione partite per chiudere le eventuali fatture.Come faccio ? ATTENZIONE: eliminata possibilita' di creare note di credito senza tipo documento CM20046 Causale senza tipo documento e con tipo movimento fattura o nota di credito. In prima nota non viene mai controllato il totale della testata presente nel campo "Voci per saldaconto" con quanto viene indicato poi nelle righe. CM20047 Causale senza tipo documento e con tipo movimento fattura/nota di credito. Se inserisco una registrazione con tipo movimento nota credito e passo successivamente ad una registrazione con causale con tipo movimento fattura, pur mettendo il codice di pagamento, la procedura non propone la pagina delle scadenze.Questo non accade se esco dalla prima nota dopo la registrazione della nota credito e rientro per registrare la fattura. CM20048 Inserisco un pagamento a fronte di un movimento nato da causale senza tipo documento e tipo movimento fattura. Se in testa indico il numero e la data del documento va tutto bene fino a che non seleziono la rata che intendo pagare, ma quando do conferma nella finestra del pagamento, la procedura mi riporta nella maschera della prima nota senza passare da quella delle partite. Solo cliccando di nuovo su conferma, la procedura mi apre la maschera delle partite. Se non indico i riferimenti del documento sulla testata della registrazione, va tutto bene. git-svn-id: svn://10.65.10.50/trunk@11508 c028cbd2-c16b-5b4b-a496-9718f37d4682
3172 lines
92 KiB
C++
Executable File
3172 lines
92 KiB
C++
Executable File
#include <colors.h>
|
||
#include <msksheet.h>
|
||
#include <progind.h>
|
||
#include <tabutil.h>
|
||
#include <urldefid.h>
|
||
#include <utility.h>
|
||
|
||
#include "cg2100.h"
|
||
#include "cg2102.h"
|
||
#include "cg21sld.h"
|
||
|
||
#include <clifo.h>
|
||
#include <cfven.h>
|
||
#include <pconti.h>
|
||
|
||
int TClinton::compare(const TSortable& obj) const
|
||
{
|
||
int cmp = TBill::compare(obj);
|
||
if (cmp == 0)
|
||
{
|
||
const TClinton& bill = (const TClinton&)obj;
|
||
cmp = _cms.compare(bill.commessa());
|
||
if (cmp == 0)
|
||
cmp = _fas.compare(bill.fase());
|
||
}
|
||
return cmp;
|
||
}
|
||
|
||
TClinton::TClinton(TToken_string& row, bool iva)
|
||
: TBill(row, iva ? 6 : 3, 0x0)
|
||
{
|
||
set_commessa(row.get((iva ? 111 : CG_COMMESSA) - FIRST_FIELD));
|
||
set_fase(row.get((iva ? 112 : CG_FASE) - FIRST_FIELD));
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Funzioni di decodifica/calcolo
|
||
///////////////////////////////////////////////////////////
|
||
|
||
// Determina il tipo di una riga contabile in formato TToken_string
|
||
char TPrimanota_application::row_type(const TToken_string& s)
|
||
{
|
||
const int l = s.len()-1;
|
||
return l > 0 ? s[l] : ' ';
|
||
}
|
||
|
||
// Determina il tipo IVA da causale+anno
|
||
// Certified 100%
|
||
TipoIVA TPrimanota_application::cau2IVA(const char* cod, int annoiva)
|
||
{
|
||
if (!read_caus(cod, annoiva))
|
||
error_box(FR("Causale errata: '%s'"), cod);
|
||
return causale().iva();
|
||
}
|
||
|
||
// Calcolo della percentuale di un dato codice IVA
|
||
// Certified 99%
|
||
const real& TPrimanota_application::cod2IVA(const TMask& m)
|
||
{
|
||
static TString16 _codiva; // Ultimo codice iva decodificato
|
||
static real _percent; // Percentuale dell'ultimo codice iva
|
||
// Tipo Costo Ricavo
|
||
if (app().iva() == iva_acquisti && m.get_int(103) == 3)
|
||
return ZERO;
|
||
|
||
const TString& codiva = m.get(102);
|
||
if (_codiva != codiva)
|
||
{
|
||
_codiva = codiva;
|
||
TCodiceIVA c(_codiva);
|
||
_percent = c.percentuale();
|
||
}
|
||
|
||
return _percent;
|
||
}
|
||
|
||
|
||
// Scorpora dall'imponibile la percentuale d'imposta(0.0%-100.0%) e ritorna l'imposta stessa
|
||
// Certified 99% Non sono sicurissimo degli imponibili negativi
|
||
real TPrimanota_application::scorpora(real& imponibile, const real& percent)
|
||
{
|
||
real imposta;
|
||
const int dec = TCurrency::get_firm_dec();
|
||
if (dec == 0) // Gestione Lire
|
||
{
|
||
imposta = abs(imponibile) * percent / (percent + 100.0);
|
||
imposta.ceil();
|
||
if (imponibile.sign() < 0) imposta = -imposta;
|
||
}
|
||
else
|
||
{ // Gestione Euro
|
||
imposta = imponibile * percent / (percent + 100.0);
|
||
imposta.round(dec);
|
||
}
|
||
imponibile -= imposta;
|
||
return imposta;
|
||
}
|
||
|
||
|
||
// Calcola il totale del documento tenendo conto del segno della prima riga e di quella delle
|
||
// ritenute sociali sulla causale
|
||
real TPrimanota_application::totale_documento()
|
||
{
|
||
const TMask& m = curr_mask();
|
||
|
||
const bool swapt = test_swap(FALSE); // Totale invertito ?
|
||
const bool swaps = test_swap(TRUE); // Ritenute sociali invertite ?
|
||
|
||
real tot(m.get(F_TOTALE)); // Legge totale
|
||
const real ritfis(m.get(F_RITFIS));
|
||
tot += ritfis; // Somma ritenute fiscali
|
||
|
||
real ritsoc(m.get(F_RITSOC));
|
||
if (swapt ^ swaps)
|
||
ritsoc = -ritsoc;
|
||
tot += ritsoc; // Somma ritenute sociali con segno
|
||
|
||
return tot;
|
||
}
|
||
|
||
|
||
// Determina se un codice sospeso o no
|
||
// Certified 99%
|
||
bool TPrimanota_application::suspended_handler(TMask_field& f, KEY k)
|
||
{
|
||
if (f.to_check(k) && !f.empty())
|
||
{
|
||
const TEdit_field& c = (const TEdit_field&)f;
|
||
const TBrowse* b = c.browse();
|
||
CHECKD(b, "Can't check suspension of an edit-field without a USE ", f.dlg());
|
||
const TLocalisamfile& i = b->cursor()->file();
|
||
// Tabella File
|
||
const char* sf = i.tab() ? "B2" : "SOSPESO";
|
||
const bool suspended = i.get_bool(sf);
|
||
if (suspended)
|
||
{
|
||
sf = f.get();
|
||
return f.error_box(TR("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 90%
|
||
bool TPrimanota_application::detraibile(TToken_string& row)
|
||
{
|
||
const TPrimanota_application& a = app();
|
||
if (a.iva() == iva_vendite) // Vendite sempre detraibili
|
||
return TRUE;
|
||
|
||
const int tipo_det = row.get_int(2); // Leggi tipo detraibilita
|
||
if (tipo_det != 0)
|
||
return FALSE;
|
||
|
||
const int annodoc = a._msk[2]->get_date(F_DATADOC).year();
|
||
const bool prorata100 = a.causale().reg().prorata100(annodoc);
|
||
return !prorata100; // Se prorata = 100% e' indetraibile
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Funzioni di ricerca
|
||
///////////////////////////////////////////////////////////
|
||
|
||
int TPrimanota_application::type2pos(char tipo)
|
||
{
|
||
TString_array& cg = app().cgs().rows_array();
|
||
for (int i = 0; i < cg.items(); i++)
|
||
{
|
||
const TToken_string& s = cg.row(i);
|
||
const char t = row_type(s);
|
||
if (t == tipo)
|
||
return i;
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
// Trova nelle righe contabili un conto nelle righe di tipo prescelto
|
||
int TPrimanota_application::bill2pos(const TBill& conto, char tipo)
|
||
{
|
||
TString_array& cg = app().cgs().rows_array();
|
||
const int num_rows = cg.items();
|
||
for (int i = 0; i < num_rows; i++)
|
||
{
|
||
TToken_string& s = cg.row(i);
|
||
const char t = row_type(s);
|
||
if (t == tipo)
|
||
{
|
||
const TBill c(s, 3, 0x0);
|
||
if (c == conto)
|
||
return i;
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
int TPrimanota_application::clint2pos(const TClinton& conto, char tipo)
|
||
{
|
||
TSheet_field& cg = app().cgs();
|
||
FOR_EACH_SHEET_ROW(cg, i, s)
|
||
{
|
||
const char t = row_type(*s);
|
||
if (t == tipo)
|
||
{
|
||
const TClinton c(*s, FALSE);
|
||
if (c == conto)
|
||
return i;
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
|
||
// Trova nelle righe contabili un conto di contropartita per il conto dato
|
||
int TPrimanota_application::bill2contr(const TBill& conto, char sezione) const
|
||
{
|
||
TString_array& rows = cgs().rows_array();
|
||
const int num_rows = rows.items();
|
||
TBill c; // Conto corrente (Buona questa!)
|
||
for (int i = 0; i < num_rows; i++)
|
||
{
|
||
TToken_string& r = rows.row(i);
|
||
const real dare(r.get(0));
|
||
const char sez = dare.is_zero() ? 'A' : 'D';
|
||
if (sez == sezione) // Devo cercare sezione contraria
|
||
continue;
|
||
c.get(r, 3, 0x0);
|
||
if (conto == c)
|
||
return i;
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
// Controlla se un conto e' usato nelle righe IVA
|
||
int TPrimanota_application::bill_used(const TBill& conto) const
|
||
{
|
||
TString_array& rows = ivas().rows_array();
|
||
TBill c; // Conto corrente
|
||
int users = 0;
|
||
for (int i = rows.items(); i >= 0 ; i--)
|
||
{
|
||
TToken_string& row = rows.row(i);
|
||
if (!row.empty_items())
|
||
{
|
||
c.get(row, 6, 0x0);
|
||
if (conto == c)
|
||
users++;
|
||
}
|
||
}
|
||
return users;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Gestione sheet CG
|
||
///////////////////////////////////////////////////////////
|
||
|
||
TSheet_field& TPrimanota_application::cgs() const
|
||
{
|
||
const TMask* m = _msk[_iva == nessuna_iva ? 1 : 2];
|
||
CHECK(m, "Null cgs() mask");
|
||
TSheet_field& s = m->sfield(F_SHEETCG);
|
||
return s;
|
||
}
|
||
|
||
|
||
// Certified 100%
|
||
// Scrive l'importo imp nella opportuna colonna della riga n
|
||
void TPrimanota_application::set_cgs_imp(int n, const TImporto& imp)
|
||
{
|
||
TSheet_field& s = cgs();
|
||
imp.add_to(s.row(n), 0);
|
||
s.force_update(n);
|
||
}
|
||
|
||
// Legge l'importo della riga n e lo ritorna col segno dovuto
|
||
// Certified 100%
|
||
TImporto TPrimanota_application::get_cgs_imp(int n) const
|
||
{
|
||
TSheet_field& s = cgs();
|
||
|
||
TImporto importo;
|
||
|
||
const TMask& m = s.sheet_mask();
|
||
if (m.is_running() && s.selected() == n)
|
||
{
|
||
const TString& imp = m.get(CG_DARE);
|
||
if (imp.not_empty())
|
||
importo.set('D', real(imp));
|
||
else
|
||
importo.set('A', real(m.get(CG_AVERE)));
|
||
}
|
||
else
|
||
importo = s.row(n);
|
||
|
||
return importo;
|
||
}
|
||
|
||
// Certified 90%
|
||
bool TPrimanota_application::add_cgs_imp(int n, const TImporto& imp)
|
||
{
|
||
TImporto tot(get_cgs_imp(n));
|
||
tot += imp;
|
||
tot.normalize();
|
||
set_cgs_imp(n, tot);
|
||
return tot.is_zero();
|
||
}
|
||
|
||
// Certified 90%
|
||
bool TPrimanota_application::sub_cgs_imp(int n, const TImporto& imp)
|
||
{
|
||
TImporto tot(get_cgs_imp(n));
|
||
tot -= imp;
|
||
tot.normalize();
|
||
set_cgs_imp(n, tot);
|
||
return tot.is_zero();
|
||
}
|
||
|
||
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)
|
||
{
|
||
TSheet_field& cg = cgs();
|
||
|
||
int first = 0, last = 0; // Range di righe da disabilitare
|
||
switch(tipo)
|
||
{
|
||
case 'T': // Totale documento
|
||
if (causale().corrispettivi())
|
||
{
|
||
last = 2;
|
||
}
|
||
else
|
||
{
|
||
last = 3;
|
||
cg.disable_cell(n, 5);
|
||
cg.disable_cell(n, 6);
|
||
}
|
||
break;
|
||
case 'A': // Abbuoni attivi
|
||
case 'C': // Differenza cambio
|
||
case 'D': // IVA Detraibile
|
||
case 'F': // Ritenute Fiscali
|
||
case 'L': // Contropartita delle spese
|
||
case 'N': // IVA Non detraibile
|
||
case 'P': // Abbuoni passivi
|
||
case 'R': // Ritenute professionali
|
||
case 'S': // Ritenute Sociali
|
||
last = 3;
|
||
break;
|
||
case 'K': // Riga cliente/fornitore per saldaconto
|
||
if (curr_mask().is_running() && n == cg.items()-1) // Sono in inserimento di una riga nuova
|
||
break;
|
||
first = 2;
|
||
case 'I':
|
||
last = 7; // Imponibile
|
||
break;
|
||
default:
|
||
last = 0; // Solo contabile
|
||
break;
|
||
}
|
||
|
||
bool needs_update = FALSE;
|
||
|
||
if (last)
|
||
{
|
||
for (int i = first; i < last; i++)
|
||
cg.disable_cell(n, i);
|
||
needs_update = TRUE;
|
||
}
|
||
|
||
// Se disabilito il sottoconto alloro spengo anche le commesse
|
||
if (cg.cell_disabled(n, 5))
|
||
{
|
||
cg.disable_cell(n, CG_COMMESSA); // Commessa
|
||
cg.disable_cell(n, CG_DESC_CDC);
|
||
cg.disable_cell(n, CG_FASE); // Fase
|
||
cg.disable_cell(n, CG_DESC_FASE);
|
||
needs_update = TRUE;
|
||
}
|
||
|
||
COLOR back_color, fore_color;
|
||
type2colors(tipo, back_color, fore_color);
|
||
if (back_color != NORMAL_BACK_COLOR || fore_color != NORMAL_COLOR)
|
||
{
|
||
cg.set_back_and_fore_color(back_color, fore_color, n);
|
||
needs_update = TRUE;
|
||
}
|
||
|
||
if (needs_update)
|
||
cg.force_update(n);
|
||
}
|
||
|
||
void TPrimanota_application::reset_sheet_row(TSheet_field& s, int n)
|
||
{
|
||
s.row(s.items()); // Append a new line
|
||
s.destroy(n); // Remove line n
|
||
}
|
||
|
||
int TPrimanota_application::set_cgs_row(int n, const TImporto& imp,
|
||
TBill& conto, const char* desc,
|
||
char tipo, const char* cms, const char* fas)
|
||
{
|
||
TSheet_field& cg = cgs();
|
||
if (n < 0) n = cg.first_empty();
|
||
TToken_string& row = cg.row(n);
|
||
row = "";
|
||
imp.add_to(row, 0);
|
||
row.add(conto.string(0x3));
|
||
row.add(""); // Codice decrizione
|
||
row.add(desc); // Descrizione aggiuntiva
|
||
|
||
if (tipo == 'T') // Calcolo contropartita
|
||
{
|
||
TToken_string& irow = ivas().row(0);
|
||
TBill contro(irow, 5, 0x3);
|
||
if (contro.ok()) // Errore MI3599
|
||
row.add(contro.string(0x3));
|
||
else
|
||
row.add(" | | | | ");
|
||
}
|
||
else
|
||
{
|
||
const int pos = type2pos('T');
|
||
if (pos >= 0)
|
||
{
|
||
TBill contro(cg.row(pos), 2, 0x3);
|
||
if (contro.ok())
|
||
row.add(contro.string(0x3));
|
||
}
|
||
else
|
||
row.add(" | | | | ");
|
||
}
|
||
|
||
if (conto.tipo() <= ' ') // Cerca di impostare la commessa sui conti normali
|
||
{
|
||
if (cms == NULL || *cms <= ' ')
|
||
{
|
||
if (row.get_char(CG_COMMESSA-FIRST_FIELD) <= ' ')
|
||
{
|
||
TString80 codcms, fascms;
|
||
if (conto.default_cdc(codcms, fascms))
|
||
{
|
||
row.add(codcms, CG_COMMESSA-FIRST_FIELD);
|
||
row.add(cache().get("CMS", codcms, "S0"), CG_DESC_CDC-FIRST_FIELD);
|
||
row.add(fascms, CG_FASE-FIRST_FIELD);
|
||
row.add(cache().get("FSC", fascms, "S0"), CG_DESC_FASE-FIRST_FIELD);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
row.add(cms, CG_COMMESSA-FIRST_FIELD);
|
||
row.add(cache().get("CMS", cms, "S0"), CG_DESC_CDC-FIRST_FIELD);
|
||
row.add(fas, CG_FASE-FIRST_FIELD);
|
||
row.add(cache().get("FSC", fas, "S0"), CG_DESC_FASE-FIRST_FIELD);
|
||
}
|
||
cg.enable_cell(n, CG_COMMESSA); // Commessa
|
||
cg.enable_cell(n, CG_DESC_CDC);
|
||
cg.enable_cell(n, CG_FASE); // Fase
|
||
cg.enable_cell(n, CG_DESC_FASE);
|
||
}
|
||
else // Azzera commessa sui conti clifo
|
||
{
|
||
row.add("", CG_COMMESSA-FIRST_FIELD);
|
||
row.add("", CG_DESC_CDC-FIRST_FIELD);
|
||
row.add("", CG_FASE-FIRST_FIELD);
|
||
row.add("", CG_DESC_FASE-FIRST_FIELD);
|
||
cg.disable_cell(n, CG_COMMESSA); // Commessa
|
||
cg.disable_cell(n, CG_DESC_CDC);
|
||
cg.disable_cell(n, CG_FASE); // Fase
|
||
cg.disable_cell(n, CG_DESC_FASE);
|
||
}
|
||
|
||
row.add(tipo, CG_ROWTYPE-FIRST_FIELD);
|
||
|
||
disable_cgs_cells(n, tipo);
|
||
|
||
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.
|
||
const char* const sort_order = "TFSI DNAPRC";
|
||
|
||
const TToken_string* r1 = (const TToken_string*)*o1;
|
||
const TToken_string* r2 = (const TToken_string*)*o2;
|
||
const char c1 = app().row_type(*r1);
|
||
const char c2 = app().row_type(*r2);
|
||
return int(strchr(sort_order, c1) - strchr(sort_order, c2));
|
||
}
|
||
|
||
HIDDEN bool can_remove(TToken_string& s)
|
||
{
|
||
const char* dare = s.get(0);
|
||
bool yes = dare == NULL ;
|
||
if (!yes)
|
||
{
|
||
if (*dare == '\0' || *dare == ' ' || strcmp(dare,"0") == 0)
|
||
{
|
||
const char* avere = s.get();
|
||
yes = (avere == NULL || *avere == '\0' || *avere == ' ' || strcmp(avere,"0") == 0);
|
||
}
|
||
}
|
||
return yes;
|
||
}
|
||
|
||
void TPrimanota_application::cgs_pack()
|
||
{
|
||
TSheet_field& s = cgs();
|
||
TString_array& rows = s.rows_array();
|
||
const bool pagamento = is_pagamento();
|
||
const long numreg = curr_mask().get_long(F_NUMREG);
|
||
|
||
for (int i = rows.items()-1; i >= 0; i--)
|
||
{
|
||
TToken_string& r = rows.row(i);
|
||
if (can_remove(r))
|
||
{
|
||
bool ok = TRUE;
|
||
if (pagamento && row_type(r) == 'K')
|
||
{
|
||
ok = !partite().utilizzata(numreg, i+1);
|
||
if (ok)
|
||
cg_notify(s, i, K_DEL);
|
||
}
|
||
if (ok)
|
||
rows.destroy(i, TRUE);
|
||
}
|
||
}
|
||
if (!pagamento) // Il pagamento e' gia' ordinato
|
||
rows.TArray::sort(compare_rows); // Pack and sort array
|
||
}
|
||
|
||
|
||
bool TPrimanota_application::ci_sono_importi() const
|
||
{
|
||
const int rows = cgs().items();
|
||
for (int i = 0; i < rows; i++)
|
||
{
|
||
const TImporto imp = get_cgs_imp(i);
|
||
if (!imp.is_zero())
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
real TPrimanota_application::calcola_saldo() const
|
||
{
|
||
TImporto importo, bilancio, saldaconto;
|
||
const bool pag = is_pagamento() && !_as400;
|
||
|
||
TString_array& rows = cgs().rows_array();
|
||
for (int i = rows.last(); i >= 0; i--)
|
||
{
|
||
TToken_string& r = rows.row(i);
|
||
importo = r;
|
||
bilancio += importo;
|
||
if (pag)
|
||
{
|
||
const char tipo = row_type(r);
|
||
if (strchr("ACGKP", tipo) != NULL) // Abbuoni attivi, differenze cambio,
|
||
saldaconto += importo;
|
||
}
|
||
}
|
||
|
||
TMask& m = curr_mask();
|
||
bilancio.normalize();
|
||
const real& sbil = bilancio.valore();
|
||
|
||
const char sez = bilancio.is_zero() ? 'Z' : bilancio.sezione();
|
||
switch (sez)
|
||
{
|
||
case 'D':
|
||
m.set(F_DARE, sbil);
|
||
m.reset(F_AVERE);
|
||
break;
|
||
case 'A':
|
||
m.reset(F_DARE);
|
||
m.set(F_AVERE, sbil);
|
||
break;
|
||
default: // Sbilancio nullo
|
||
m.reset(F_DARE);
|
||
m.reset(F_AVERE);
|
||
break;
|
||
}
|
||
|
||
if (pag)
|
||
{
|
||
const char s(causale().sezione(2)); // Conto della cassa
|
||
const real t(m.get(F_TOTALE));
|
||
TImporto totdoc(s, t);
|
||
totdoc += saldaconto;
|
||
totdoc.normalize(s);
|
||
m.set(K_RESIDUO, totdoc.valore().string());
|
||
}
|
||
|
||
return sbil;
|
||
}
|
||
|
||
HIDDEN bool imptot_error(const TImporto& imptot, const TImporto& impsal, bool val)
|
||
{
|
||
TImporto cassa(impsal); cassa.swap_section();
|
||
TImporto residuo(imptot); residuo -= cassa; residuo.normalize(imptot.sezione());
|
||
bool ok = TRUE;
|
||
|
||
// if (!residuo.is_zero())
|
||
if (abs(residuo.valore()) >= 0.001)
|
||
{
|
||
TPrimanota_application& a = app();
|
||
const TMask& m = a.curr_mask();
|
||
TString16 codval;
|
||
if (val)
|
||
codval = m.get(SK_VALUTA);
|
||
TCurrency euro(imptot.valore(), codval);
|
||
|
||
TString msg(255);
|
||
if (codval.not_empty())
|
||
msg << TR("Il totale documento in valuta") << ' ' << codval;
|
||
else
|
||
msg << TR("Il totale documento inserito");
|
||
msg << TR(" e' ") << euro.string(TRUE) << ' ' << imptot.sezione() << ",\n";
|
||
|
||
euro.set_num(cassa.valore());
|
||
msg << TR("i pagamenti e le spese ammontano a ")
|
||
<< euro.string(TRUE) << ' ' << cassa.sezione() << ",\n";
|
||
|
||
euro.set_num(residuo.valore());
|
||
msg << TR("per cui il residuo e' ") << euro.string(TRUE);
|
||
|
||
if (m.edit_mode() && impsal.is_zero())
|
||
{
|
||
msg << TR("\nSi desidera registrare ugualmente?");
|
||
ok = a.cgs().yesno_box(msg);
|
||
}
|
||
else
|
||
ok = a.cgs().error_box(msg);
|
||
}
|
||
|
||
return ok;
|
||
}
|
||
|
||
// Handler dello sheet di contabilita'
|
||
// Certified 90%
|
||
bool TPrimanota_application::cg_handler(TMask_field& f, KEY k)
|
||
{
|
||
if (k == K_ENTER)
|
||
{
|
||
TPrimanota_application& a = app();
|
||
const TCurrency saldo(a.calcola_saldo());
|
||
|
||
if (!saldo.get_num().is_zero())
|
||
{
|
||
const char* ss = saldo.string(TRUE);
|
||
if (*ss == '-') ss++;
|
||
|
||
const TRectype& rec = cache().get("%VAL", TCurrency::get_firm_val());
|
||
const char* name = rec.get("S0");
|
||
return f.error_box(FR("Il movimento e' sbilanciato di %s %s."), ss, name);
|
||
}
|
||
|
||
TMask& m = f.mask();
|
||
const bool paga = a.is_pagamento();
|
||
const bool nota = a.is_nota_credito() && m.field(F_NUMRIF).active();
|
||
const bool fatt = a.is_fattura() && m.page_enabled(2);
|
||
|
||
const long numreg = m.insert_mode() ? NUMREG_PROVVISORIO : m.get_long(F_NUMREG);
|
||
|
||
const bool in_valuta = m.get(SK_VALUTA).not_empty();
|
||
TImporto saldaconto, saldaconto_val;
|
||
|
||
TSheet_field& cg = a.cgs();
|
||
bool empty = TRUE;
|
||
for (int i = 0; i < cg.items(); i++)
|
||
{
|
||
TToken_string& r = cg.row(i);
|
||
TImporto importo; importo = r;
|
||
|
||
if (!importo.is_zero())
|
||
{
|
||
TBill c(r, 2, 0x1);
|
||
if (!c.ok())
|
||
return f.error_box(FR("Il conto della riga %d non e' completo"), i+1);
|
||
if (m.insert_mode() && c.sospeso())
|
||
return f.error_box(FR("Il conto della riga %d e' sospeso"), i+1);
|
||
TBill co(r, 10, 0x0);
|
||
if (!co.empty() && !co.ok())
|
||
{
|
||
const bool ok = f.yesno_box(FR("La contropartita della riga %d non e' completa:\n"
|
||
"Si desidera continuare ugualmente?"), i+1);
|
||
if (!ok) return FALSE;
|
||
}
|
||
|
||
if (app().is_transaction())
|
||
{
|
||
// Controlla esistenza conti nelle transazioni (visto che non c'e' controllo in inserimento)
|
||
if (!c.find())
|
||
return f.error_box("Il conto della riga %d non esiste", i+1);
|
||
if (!co.empty() && !co.find())
|
||
return f.error_box("Il conto di contropartita della riga %d non esiste", i+1);
|
||
}
|
||
|
||
empty = FALSE;
|
||
if (paga || nota)
|
||
{
|
||
const char tipo = row_type(r);
|
||
if (tipo == 'K' || tipo == 'T' || a._as400)
|
||
{
|
||
const int currig = i+1;
|
||
const TImporto speso = a.partite().importo_speso(numreg, currig);
|
||
|
||
bool errato = importo != speso;
|
||
if (errato && a._as400 && speso.is_zero())
|
||
errato = FALSE;
|
||
|
||
if (nota && errato && speso.is_zero())
|
||
{
|
||
const int annorif = m.get_int(F_ANNORIF);
|
||
const TString& numrif = m.get(F_NUMRIF);
|
||
if (annorif > 0 && !numrif.blank() &&
|
||
yesno_box(FR("Si desidera generare automaticamente la partita %d %s?"),
|
||
annorif, (const char*)numrif))
|
||
{
|
||
const TBill bill(r, 2, 0x1);
|
||
errato = !a.crea_partita(bill, annorif, numrif, currig, importo);
|
||
}
|
||
}
|
||
|
||
if (errato)
|
||
{
|
||
TString msg(128);
|
||
const TCurrency euro(speso.valore());
|
||
msg.format("L'importo sul saldaconto della riga %d e' %s", currig, (const char*)euro.string(TRUE));
|
||
if (!speso.is_zero())
|
||
msg << (speso.sezione() == 'A' ? TR(" Avere") : TR(" Dare"));
|
||
|
||
bool ok = FALSE;
|
||
if (m.edit_mode() && speso.is_zero())
|
||
{
|
||
msg << TR("\nSi desidera registrare ugualmente?");
|
||
ok = f.yesno_box(msg);
|
||
}
|
||
else
|
||
ok = f.error_box(msg);
|
||
if (!ok)
|
||
return FALSE;
|
||
}
|
||
}
|
||
if (strchr("ACGKPT", tipo) != NULL)
|
||
{
|
||
saldaconto += importo;
|
||
if (in_valuta)
|
||
{
|
||
if (tipo == 'G') // Le spese non si trovano sul saldaconto
|
||
{
|
||
const TExchange cam(m.get(SK_VALUTA), m.get_real(SK_CAMBIO));
|
||
TCurrency spe(importo.valore()); spe.change_value(cam);
|
||
const TImporto imp_spe(importo.sezione(), spe.get_num());
|
||
saldaconto_val += imp_spe;
|
||
} else
|
||
if (tipo == 'K' || tipo == 'T')
|
||
saldaconto_val += a.partite().importo_speso(numreg, i+1, TRUE, 0x1);
|
||
}
|
||
}
|
||
}
|
||
|
||
// La commessa <20> vuota: controlliamo se era obbligatoria
|
||
const TString80 cms = r.get(CG_COMMESSA-FIRST_FIELD);
|
||
if (c.tipo() <= ' ' && cms.blank())
|
||
{
|
||
TToken_string k = c.string();
|
||
const TRectype& pc = cache().get(LF_PCON, k);
|
||
if (pc.get_bool(PCN_CMSNEEDED))
|
||
{
|
||
k.replace('|', ' ');
|
||
return f.error_box(FR("Il codice commessa <20> obbligatorio per il conto %s della riga %d"),
|
||
(const char*)k, i+1);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (empty)
|
||
return f.error_box(TR("Il movimento non ha nessuna riga contabile con un importo"));
|
||
|
||
if ((paga || nota) && !a._as400)
|
||
{
|
||
const char sez(a.causale().sezione(2));
|
||
const TImporto totdoc(sez, m.get_real(F_TOTALE));
|
||
bool ok = imptot_error(totdoc, saldaconto, FALSE);
|
||
|
||
if (ok && in_valuta && !saldaconto.is_zero())
|
||
{
|
||
const TImporto totdoc_val(sez, m.get_real(SK_TOTDOCVAL));
|
||
ok = imptot_error(totdoc_val, saldaconto_val, TRUE);
|
||
}
|
||
|
||
if (!ok)
|
||
return FALSE;
|
||
}
|
||
|
||
if (fatt || nota)
|
||
{
|
||
TBill contocf;
|
||
const int riga_cf = a.cerca_conto_cf(contocf);
|
||
if (riga_cf < 0)
|
||
{
|
||
TString msg(80); msg = TR("Non esiste una riga contabile riferita al ");
|
||
msg << (contocf.tipo() == 'C' ? TR("cliente") : TR("fornitore")) << ' ';
|
||
msg << contocf.codclifo() << ":\n";
|
||
if (m.edit_mode())
|
||
{
|
||
msg << TR("Si desidera eliminare il saldaconto?");
|
||
const bool kill = f.yesno_box(msg);
|
||
if (kill)
|
||
{
|
||
if (fatt) // Se e' una fattura elimina il numero partita
|
||
{
|
||
m.reset(F_ANNORIF);
|
||
m.reset(F_NUMRIF);
|
||
}
|
||
else
|
||
{ // Se e' una nota credito elimina il saldaconto
|
||
a.notify_cgline_deletion(-1);
|
||
}
|
||
}
|
||
else
|
||
return FALSE;
|
||
}
|
||
else
|
||
{
|
||
msg << TR("Impossibile registrare il saldaconto!");
|
||
return f.error_box(msg);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
void TPrimanota_application::generazione_righe_cg(int r)
|
||
{
|
||
TSheet_field& cg = cgs();
|
||
TToken_string& row = cg.row(r);
|
||
|
||
if (can_remove(row)) // Ignora righe senza importo
|
||
return;
|
||
|
||
TWait_cursor hourglass;
|
||
|
||
TImporto importo; importo = row;
|
||
const bool causale_ok = causale().codice()[0] > ' ';
|
||
|
||
// Se la seconda riga e' vuota la genero completamente dalla prima
|
||
if (r == 0 && cg.row(1).empty_items())
|
||
{
|
||
TBill contro(row, 9, 0x3); // Contropartita della prima riga
|
||
if (causale_ok && !contro.ok())
|
||
{
|
||
causale().bill(2, contro); // Prendi contropartita dalla causale
|
||
if (contro.ok())
|
||
{
|
||
contro.add_to(row, 9, 0x3);
|
||
cg.force_update(0);
|
||
}
|
||
}
|
||
if (contro.ok())
|
||
{
|
||
importo.swap_section(); // Inverto la sezione D/A
|
||
set_cgs_row(1, importo, contro, "", ' ');
|
||
TBill conto(row, 2, 0x3);
|
||
conto.add_to(cg.row(1), 9, 0x3);
|
||
cg.force_update(1);
|
||
}
|
||
}
|
||
|
||
if (causale_ok)
|
||
{
|
||
int first_not_empty = 0;
|
||
for (int i = 0; i < r; i++)
|
||
{
|
||
TToken_string& row = cg.row(i);
|
||
if (!can_remove(row))
|
||
{
|
||
first_not_empty = i;
|
||
break;
|
||
}
|
||
}
|
||
|
||
TBill conto(row, 2, 0x3);
|
||
if (first_not_empty == r) // Sono la prima riga con importo ?
|
||
{
|
||
int last = -1;
|
||
for (i = r+1; i < cg.items(); i++) // Aggiorna tutte le altre contropartite
|
||
{
|
||
TToken_string& rowi = cg.row(i);
|
||
int gruppo = rowi.get_int(3);
|
||
if (gruppo != 0) // Considera righe con conto ...
|
||
{
|
||
long sotto = rowi.get_long(12);
|
||
if (sotto == 0) // ... e senza contropartita
|
||
{
|
||
char sez = ' '; // Calcola sezione D/A della riga i
|
||
if (cg.cell_disabled(i,0)) sez = 'A'; else
|
||
if (cg.cell_disabled(i,1)) sez = 'D';
|
||
|
||
if (sez != ' ' && importo.sezione() != sez) // Considera solo le sezioni opposte
|
||
{
|
||
conto.add_to(rowi, 9, 0x3);
|
||
cg.force_update(i);
|
||
if (last < 0) last = i;
|
||
else last = 0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if (last > r)
|
||
{
|
||
importo.swap_section();
|
||
set_cgs_imp(last, importo);
|
||
|
||
const long sotto = row.get_long(12);
|
||
if (sotto == 0) // Se non ho contropartita ...
|
||
{
|
||
TBill contro(cg.row(last), 2, 0x3); // ... copiala dalla riga corrispondente
|
||
contro.add_to(row, 9, 0x3);
|
||
cg.force_update(r);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
TToken_string& first = cg.row(first_not_empty);
|
||
long sotto = first.get_long(12);
|
||
if (sotto == 0) // Se la prima riga non ha contropartita ...
|
||
{
|
||
conto.add_to(first, 9, 0x3); // ... copiaci la mia partita
|
||
cg.force_update(first_not_empty);
|
||
}
|
||
sotto = row.get_long(12);
|
||
if (sotto == 0) // Se non ho contropartita ...
|
||
{
|
||
TBill contro(first, 2, 0x3); // ... copiala dalla prima riga
|
||
contro.add_to(row, 9, 0x3);
|
||
cg.force_update(r);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
int TPrimanota_application::crea_somma_spese(TImporto& imp)
|
||
{
|
||
TBill cassa; causale().bill(2, cassa);
|
||
const TString desc(causale().desc_agg(2));
|
||
imp.swap_section(); imp.normalize();
|
||
const int r = set_cgs_row(-1, imp, cassa, desc, 'L');
|
||
cgs().force_update();
|
||
return r;
|
||
}
|
||
|
||
void TPrimanota_application::update_saldo_riga(int r)
|
||
{
|
||
TSheet_field& sheet = cgs();
|
||
TToken_string row = sheet.row(r);
|
||
TBill bill; bill.get(row, 2, 0x1);
|
||
|
||
if (bill.ok())
|
||
{
|
||
TMask& m = curr_mask();
|
||
const int annoes = m.get_int(F_ANNOES);
|
||
|
||
// Legge il saldo finale del conto
|
||
TBalance bilancio;
|
||
bilancio.read(bill, annoes, false, false);
|
||
TImporto saldo = bilancio.saldo_finale();
|
||
|
||
// Sottrae (somma algebricamente) il valore iniziale del conto
|
||
const TConto* conto = _saldi.find(bill, annoes);
|
||
if (conto != NULL)
|
||
{
|
||
saldo += TImporto('D', conto->dare());
|
||
saldo += TImporto('A', conto->avere());
|
||
}
|
||
|
||
// Somma l'importo delle singole righe con quel conto
|
||
for (int i = sheet.items()-1; i >= 0; i--)
|
||
{
|
||
row = sheet.row(i);
|
||
if (!row.empty_items())
|
||
{
|
||
TBill zio; zio.get(row, 2, 0x1);
|
||
if (zio == bill)
|
||
{
|
||
TImporto da; da = row;
|
||
saldo += da;
|
||
}
|
||
}
|
||
}
|
||
|
||
TString80 s; // Stringa di lavoro
|
||
|
||
// Trasforma il saldo in stringa
|
||
saldo.normalize();
|
||
if (!saldo.is_zero())
|
||
{
|
||
const TCurrency imp = saldo.valore();
|
||
s = imp.string(true);
|
||
s << ' ' << saldo.sezione();
|
||
}
|
||
|
||
bill.set(m, F_GRUPPO, F_CONTO, F_SOTTOCONTO); // Stampa conto
|
||
m.set(F_SALDOCONTO, s); // Stampa saldo
|
||
|
||
// Controlla se il conto ha attivato il controllo del segno
|
||
s = bill.string(); // Chiave del sottoconto da controllare
|
||
if (bill.tipo() > ' ') // Per i clienti/fornitori devo controllare il solo gruppo/conto
|
||
{
|
||
const int pipe = s.rfind('|');
|
||
s.cut(pipe);
|
||
}
|
||
const TRectype& pcon = cache().get(LF_PCON, s);
|
||
const char sez = pcon.get_char(PCN_SEZSALDI);
|
||
bool red = false;
|
||
if (sez > ' ' && !saldo.is_zero()) // Il conto ha impostato il controllo della sezione!
|
||
red = sez != saldo.sezione();
|
||
|
||
// Scrive in nero o rosso la parola Saldo
|
||
s = TR("Saldo");
|
||
if (red)
|
||
{
|
||
s.upper();
|
||
s.insert("@b$[r]");
|
||
}
|
||
m.field(F_SALDOCONTO).set_prompt(s);
|
||
}
|
||
}
|
||
|
||
bool TPrimanota_application::cg_notify(TSheet_field& cg, int r, KEY k)
|
||
{
|
||
static TImporto old_spesa;
|
||
static bool delete_l = FALSE;
|
||
static bool selecting = FALSE;
|
||
|
||
CHECKD(r >= 0, "Chi e' quel ca$$one che notifica la riga ", r);
|
||
|
||
TPrimanota_application& a = app();
|
||
|
||
if (k == K_CTRL + K_DEL)
|
||
{
|
||
if (delete_l)
|
||
{
|
||
const int l = type2pos('L');
|
||
CHECK(l >= 0, "Impossibile cancellare riga di tipo L");
|
||
cg.destroy(l);
|
||
delete_l = FALSE;
|
||
}
|
||
a.calcola_saldo(); // Ricalcola saldo dopo cancellazione
|
||
return TRUE; // Ritorna subito, altrimenti crea riga vuota
|
||
}
|
||
|
||
if (k == K_INS) // La riga non esiste ancora
|
||
return TRUE;
|
||
|
||
TToken_string& row = cg.row(r);
|
||
const char tipo = row_type(row); // Tipo della riga in esame
|
||
|
||
switch(k)
|
||
{
|
||
case K_SPACE:
|
||
if (tipo == 'G')
|
||
old_spesa = row;
|
||
else
|
||
old_spesa.valore() = ZERO;
|
||
break;
|
||
case K_TAB:
|
||
if (!selecting)
|
||
{
|
||
cg.sheet_mask().enable(DLG_DELREC, tipo <= ' ' || tipo == 'K' || tipo == 'G');
|
||
if (row.empty_items())
|
||
{
|
||
selecting = TRUE;
|
||
cg.select(r, 1); // Vado alla prima colonna delle righe vuote
|
||
selecting = FALSE;
|
||
}
|
||
a.update_saldo_riga(r);
|
||
}
|
||
break;
|
||
case K_DEL:
|
||
if (tipo == 'G')
|
||
{
|
||
if (old_spesa.is_zero())
|
||
old_spesa = row;
|
||
row.add("", 0);
|
||
row.add("", 1);
|
||
}
|
||
else
|
||
{
|
||
if (tipo == 'K')
|
||
a.notify_cgline_deletion(r+1);
|
||
break;
|
||
}
|
||
case K_ENTER:
|
||
if (tipo == 'G')
|
||
{
|
||
TImporto growth; growth = row; growth -= old_spesa;
|
||
if (!growth.is_zero())
|
||
{
|
||
const int s = type2pos('L');
|
||
if (s < 0)
|
||
a.crea_somma_spese(growth);
|
||
else
|
||
delete_l = a.sub_cgs_imp(s, growth);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (a.iva() == nessuna_iva && !a.is_saldaconto())
|
||
a.generazione_righe_cg(r);
|
||
}
|
||
if (k == K_ENTER)
|
||
{
|
||
a.calcola_saldo(); // Altrimenti ci pensa CTRL-DEL
|
||
}
|
||
break;
|
||
case K_CTRL+K_INS: // Post inserimento
|
||
if (a.is_pagamento())
|
||
{
|
||
const char tipo = cg.mask().get(SK_TIPORIGA)[0];
|
||
if (tipo == 'K' || tipo == 'G')
|
||
{
|
||
const int k = tipo == 'K' ? 1 : RIGA_SPESE;
|
||
TBill conto; a.causale().bill(k, conto);
|
||
const TString desc(a.causale().desc_agg(k));
|
||
const char sez = a.causale().sezione(k);
|
||
const real imp = cg.mask().get(K_RESIDUO);
|
||
TImporto importo(sez, imp); importo.normalize();
|
||
|
||
if (tipo == 'G')
|
||
{
|
||
const char sezbanca = a.causale().sezione(2);
|
||
if (sezbanca == sez)
|
||
importo.swap_section();
|
||
}
|
||
|
||
a.set_cgs_row(r, importo, conto, desc, tipo);
|
||
|
||
if (tipo == 'K')
|
||
{
|
||
for (int i = 0; i < r; i++)
|
||
{
|
||
const TToken_string& row = cg.row(i);
|
||
if (row_type(row) != 'K')
|
||
{
|
||
cg.swap_rows(r, i);
|
||
cg.post_select(i);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (!importo.is_zero())
|
||
{
|
||
const int s = type2pos('L');
|
||
if (s < 0)
|
||
a.crea_somma_spese(importo);
|
||
else
|
||
a.sub_cgs_imp(s, importo);
|
||
}
|
||
}
|
||
a.calcola_saldo();
|
||
}
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
bool TPrimanota_application::descr_handler(TMask_field& f, KEY k)
|
||
{
|
||
if (k == K_TAB && f.focusdirty())
|
||
{
|
||
if (app().iva() != nessuna_iva)
|
||
{
|
||
const int first = type2pos('T');
|
||
if (first >= 0)
|
||
{
|
||
TSheet_field& cg = app().cgs();
|
||
const TString80 old = cg.row(first).get(8);
|
||
if (old.blank() || f.get().find(old) >= 0)
|
||
{
|
||
cg.row(first).add(f.get(), 8);
|
||
cg.force_update(first);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if (k == K_ENTER && f.get().empty())
|
||
{
|
||
if (f.mask().get(F_CODCAUS).empty())
|
||
return f.error_box(TR("La descrizione del documento e' necessaria in assenza 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)
|
||
{
|
||
TPrimanota_application& a = app();
|
||
TSheet_field& cgs = a.cgs();
|
||
const int currig = cgs.selected();
|
||
TMask& m = f.mask();
|
||
|
||
if (k == K_F8 && a.is_pagamento())
|
||
{
|
||
const TMask& cm = a.curr_mask();
|
||
const long numreg = cm.insert_mode() ? NUMREG_PROVVISORIO : cm.get_long(F_NUMREG);
|
||
const TImporto speso = a.partite().importo_speso(numreg, currig+1);
|
||
|
||
const char* ss = speso.valore().string();
|
||
m.set(CG_DARE, speso.sezione() == 'D' ? ss : "");
|
||
m.set(CG_AVERE, speso.sezione() == 'A' ? ss : "");
|
||
|
||
if (!m.is_running())
|
||
{
|
||
speso.add_to(cgs.row(currig), 0); // Aggiorna riga sheet
|
||
a.calcola_saldo(); // Aggiorna saldo e residuo
|
||
a.update_saldo_riga(currig);
|
||
}
|
||
}
|
||
|
||
if (k == K_TAB && f.focusdirty())
|
||
{
|
||
const TString& val = f.get();
|
||
TToken_string& row = cgs.row(currig);
|
||
row.add(val, f.dlg() - CG_DARE); // Aggiorno stringa sheet
|
||
|
||
if (val.not_empty())
|
||
{
|
||
// Calcola id del campo da resettare
|
||
const int id = f.dlg() == CG_DARE ? CG_AVERE : CG_DARE;
|
||
m.reset(id); // Aggiorna maschera e ...
|
||
row.add("", id - CG_DARE); // ... riga dello sheet
|
||
}
|
||
|
||
if (!m.is_running())
|
||
{
|
||
a.calcola_saldo(); // Aggiorna saldo e residuo
|
||
a.update_saldo_riga(currig);
|
||
}
|
||
}
|
||
|
||
if (k == K_ENTER && f.dirty() && m.is_running())
|
||
{
|
||
a.calcola_saldo(); // Aggiorna saldo e residuo
|
||
a.update_saldo_riga(currig);
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
// La fase puo' esistere solo con la commessa
|
||
bool TPrimanota_application::fase_handler(TMask_field& f, KEY k)
|
||
{
|
||
bool ok = TRUE;
|
||
if (f.to_check(k) && !f.empty())
|
||
{
|
||
const TEdit_field& cms_fld = f.mask().efield(f.dlg()-1);
|
||
if (cms_fld.empty())
|
||
ok = f.error_box(TR("E' necessario specificare anche la commessa"));
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
TSheet_field& TPrimanota_application::pags() const
|
||
{
|
||
CHECK(is_fattura(), "Can't use rate sheet without a fattura");
|
||
TMask& m = *_msk[iva() == nessuna_iva ? 1 : 2];
|
||
return m.sfield(FS_RATESHEET);
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Gestione sheet IVA
|
||
///////////////////////////////////////////////////////////
|
||
|
||
// Ritorna lo sheet delle righe IVA
|
||
// Certified 100%
|
||
TSheet_field& TPrimanota_application::ivas() const
|
||
{
|
||
TSheet_field& s = _msk[2]->sfield(F_SHEETIVA);
|
||
return s;
|
||
}
|
||
|
||
// Gestione del campo imponibile sullo sheet iva
|
||
// Certified 99%
|
||
bool TPrimanota_application::imponibile_handler(TMask_field& f, KEY key)
|
||
{
|
||
if (key == K_TAB && f.dirty())
|
||
{
|
||
TMask& m = f.mask();
|
||
TString16 iva(m.get(102));
|
||
if (iva.empty())
|
||
{
|
||
iva = app().curr_mask().get(F_CODIVA);
|
||
if (iva.not_empty())
|
||
m.set(102, iva, TRUE);
|
||
}
|
||
if (iva.not_empty() && !app().causale().corrispettivi())
|
||
{
|
||
const real& percent = cod2IVA(m);
|
||
const real imponibile(f.get());
|
||
const int dec = TCurrency::get_firm_dec();
|
||
real imposta;
|
||
if (dec == 0)
|
||
{
|
||
imposta = abs(imponibile) * percent / 100.0;
|
||
imposta.ceil();
|
||
if (imponibile.sign() < 0) imposta = -imposta;
|
||
}
|
||
else
|
||
{
|
||
imposta = imponibile * percent / 100.0;
|
||
imposta.round(dec);
|
||
}
|
||
m.set(104, imposta);
|
||
}
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
// Gestione del codice IVA sullo sheet iva
|
||
// Certified 90%
|
||
bool TPrimanota_application::codiva_handler(TMask_field& f, KEY key)
|
||
{
|
||
if (!suspended_handler(f, key))
|
||
return FALSE;
|
||
|
||
if (key == K_TAB && f.dirty())
|
||
{
|
||
TMask& m = f.mask();
|
||
TCodiceIVA iva(f.get());
|
||
|
||
if (m.get_int(107) == 0)
|
||
{
|
||
TBill b; app().IVA2bill(iva, b);
|
||
|
||
char cr[2] = { b.tipo_cr() + '0', '\0' };
|
||
m.set(105, *cr > '0' ? cr : "");
|
||
|
||
const char tipo[2] = { b.tipo(), '\0' };
|
||
m.set(106, tipo);
|
||
m.set(107, b.gruppo());
|
||
m.set(108, b.conto());
|
||
const short id = b.tipo() == 'C' ? 209 : (b.tipo() == 'F' ? 309 : 109);
|
||
m.set(id, b.sottoconto());
|
||
m.set(id+1, b.descrizione());
|
||
|
||
TString80 codcms, fascms;
|
||
if (b.default_cdc(codcms, fascms))
|
||
{
|
||
m.set(111, codcms, TRUE);
|
||
m.set(112, fascms, TRUE);
|
||
}
|
||
}
|
||
|
||
if (app().iva() == iva_acquisti)
|
||
{
|
||
const int det = iva.detraibilita();
|
||
if (det > 0)
|
||
m.set(103, det);
|
||
}
|
||
|
||
TMask_field& im = m.field(101);
|
||
im.set_dirty();
|
||
im.on_hit();
|
||
}
|
||
else
|
||
{
|
||
if (key == K_ENTER)
|
||
{
|
||
if (f.get().empty() && f.mask().get(101).not_empty())
|
||
return f.error_box(TR("Codice IVA obbligatorio"));
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
// Gestione del codice detrazione sullo sheet iva
|
||
// Certified 90%
|
||
bool TPrimanota_application::detrazione_handler(TMask_field& f, KEY key)
|
||
{
|
||
if (key == K_TAB && f.dirty() && app().iva() == iva_acquisti)
|
||
{
|
||
TMask& m = f.mask();
|
||
TMask_field& ci = m.field(101);
|
||
ci.set_dirty();
|
||
ci.on_hit();
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
// Gestione del campo imposta sullo sheet iva
|
||
// Certified 90%
|
||
bool TPrimanota_application::imposta_handler(TMask_field& f, KEY key)
|
||
{
|
||
TMask& m = f.mask();
|
||
if ((key == K_ENTER || key == K_TAB) && f.dirty())
|
||
{
|
||
const real imponibile(m.get(101));
|
||
const real percent = app().causale().corrispettivi() ? ZERO : cod2IVA(m);
|
||
const int dec = TCurrency::get_firm_dec();
|
||
real imposta;
|
||
if (dec == 0)
|
||
{
|
||
imposta = abs(imponibile) * percent / 100.0;
|
||
imposta.ceil();
|
||
if (imponibile.sign() < 0) imposta = -imposta;
|
||
}
|
||
else
|
||
{
|
||
imposta = imponibile * percent / 100.0;
|
||
imposta.round(dec);
|
||
}
|
||
|
||
const real val(f.get());
|
||
if (val != imposta)
|
||
{
|
||
const TCurrency euro(imposta);
|
||
f.warning_box(FR("L'imposta dovrebbe essere %s"), euro.string(TRUE));
|
||
}
|
||
} else
|
||
if (key == K_F8)
|
||
{
|
||
real imposta(f.get());
|
||
if (imposta.is_zero())
|
||
{
|
||
real imponibile(m.get(101));
|
||
const real& percent = cod2IVA(m);
|
||
imposta = scorpora(imponibile, percent);
|
||
m.set(101, imponibile);
|
||
f.set(imposta.string());
|
||
}
|
||
else
|
||
f.warning_box(TR("Cancellare l'imposta (tasto F2) prima di effettuare lo scorporo"));
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
// Calcola il totale degli imponibili e delle imposte e aggiorna
|
||
// i corrispondenti campi della maschera
|
||
// Certified 99%
|
||
real TPrimanota_application::calcola_imp() const
|
||
{
|
||
TArray& rows = ivas().rows_array();
|
||
|
||
real imponibili, imposte;
|
||
for (int r = rows.items()-1; r >= 0; r--)
|
||
{
|
||
TToken_string& row = (TToken_string&)rows[r];
|
||
imponibili += real(row.get(0));
|
||
imposte += real(row.get(3));
|
||
}
|
||
|
||
TMask& m = curr_mask();
|
||
m.set(F_IMPONIBILI, imponibili);
|
||
m.set(F_IMPOSTE, imposte);
|
||
|
||
// Se e' attiva la terza pagina allora riporta i totali in testata
|
||
if (is_fattura())
|
||
{
|
||
real tot(m.get(F_TOTALE)); tot -= imposte;
|
||
m.set(FS_IMPONIBILI, tot);
|
||
m.set(FS_IMPOSTE, imposte);
|
||
}
|
||
|
||
return imponibili+imposte;
|
||
}
|
||
|
||
// Elimina dallo sheet le righe iva senza importi (imponibile e imposta)
|
||
// Certified 99%
|
||
void TPrimanota_application::ivas_pack()
|
||
{
|
||
TString_array& rows = ivas().rows_array();
|
||
|
||
const int max = rows.items();
|
||
for (int i = 0; i < max; i++)
|
||
{
|
||
TToken_string& r = rows.row(i);
|
||
const real imponibile(r.get(0));
|
||
if (imponibile != ZERO) continue;
|
||
const real imposta(r.get(3));
|
||
if (imposta != ZERO) continue;
|
||
rows.destroy(i, FALSE);
|
||
}
|
||
|
||
rows.pack(); // Pack array
|
||
}
|
||
|
||
// Certified 50%
|
||
bool TPrimanota_application::iva_notify(TSheet_field& iva, int r, KEY k)
|
||
{
|
||
static int oldpos,oldposiva;
|
||
static TImporto oldimp, oldiva;
|
||
static bool selecting = FALSE;
|
||
|
||
TPrimanota_application& a = app();
|
||
if (a._as400)
|
||
return TRUE;
|
||
|
||
if (k == K_INS || k == K_CTRL+K_DEL)
|
||
return TRUE;
|
||
|
||
TToken_string& row = iva.row(r);
|
||
const TCausale& cau = a.causale();
|
||
|
||
if (k == K_TAB)
|
||
{
|
||
if (!selecting && row.empty_items())
|
||
{
|
||
selecting = TRUE;
|
||
iva.select(r, 1); // Vado alla prima colonna delle righe vuote
|
||
selecting = FALSE;
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
if (k == K_SPACE)
|
||
{
|
||
oldimp = a.real2imp(real(row.get(0)), 'I'); // Imponibile
|
||
oldiva = a.real2imp(real(row.get(3)), 'I'); // Imposta
|
||
|
||
if (oldiva.is_zero() && cau.corrispettivi()) // In caso di corrispettivi ...
|
||
{
|
||
const TString16 zanicchi(row.get(1)); // Codice IVA
|
||
const TCodiceIVA i(zanicchi);
|
||
oldiva.valore() = i.scorpora(oldimp.valore()); // ... scorpora imposta dall'imponibile
|
||
}
|
||
|
||
const char tipod = detraibile(row) ? 'D' : 'N';
|
||
oldposiva = type2pos(tipod);
|
||
|
||
if (oldposiva < 0 && !oldiva.is_zero())
|
||
{
|
||
const int ri = tipod == 'D' ? RIGA_IVA_DETRAIBILE : RIGA_IVA_NON_DETRAIBILE;
|
||
TBill c; cau.bill(ri, c);
|
||
if (c.ok())
|
||
{
|
||
const TString80 d(cau.desc_agg(ri));
|
||
oldposiva = a.set_cgs_row(-1, a.real2imp(ZERO, 'I'), c, d, tipod);
|
||
}
|
||
else
|
||
if (ri == 4) // Se non esiste il conto IVA indetraibile ...
|
||
{ // ... somma imponibile e imposta
|
||
oldimp += oldiva;
|
||
oldiva.set('D', ZERO);
|
||
}
|
||
}
|
||
|
||
TClinton oldconto(row, TRUE);
|
||
if (oldconto.ok())
|
||
{
|
||
oldpos = clint2pos(oldconto, 'I');
|
||
if (oldpos < 0)
|
||
{
|
||
const TString d(cau.desc_agg(2));
|
||
oldpos = a.set_cgs_row(-1, a.real2imp(ZERO, 'I'), oldconto, d, 'I', oldconto.commessa(), oldconto.fase());
|
||
}
|
||
}
|
||
else
|
||
oldpos = -1; // Se il conto e' incompleto ignoralo
|
||
}
|
||
if (k == K_DEL) // Cancellazione di una riga
|
||
{
|
||
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)
|
||
{
|
||
int delimp = -1, deliva = -1; // Eventuali righe contabili da cancellare
|
||
if (oldpos >= 0) // Se il conto esisteva anche prima ...
|
||
{ // sottrai il vecchio imponibile
|
||
TImporto i(a.get_cgs_imp(oldpos));
|
||
i -= oldimp;
|
||
i.normalize();
|
||
a.set_cgs_imp(oldpos, i);
|
||
if (i.is_zero())
|
||
delimp = oldpos;
|
||
}
|
||
if (oldposiva >= 0) // Se conto IVA esisteva anche prima ...
|
||
{ // sottrai la vecchia imposta
|
||
TImporto i(a.get_cgs_imp(oldposiva));
|
||
i -= oldiva;
|
||
i.normalize();
|
||
a.set_cgs_imp(oldposiva, i);
|
||
if (i.is_zero())
|
||
deliva = oldposiva;
|
||
}
|
||
|
||
real imponibile(row.get(0)); // Nuovo imponibile
|
||
real imposta(row.get(3)); // Nuova imposta
|
||
|
||
if (imposta.is_zero() && cau.corrispettivi()) // In caso di corrispettivi ...
|
||
{
|
||
const TString zanicchi(row.get(1));
|
||
const TCodiceIVA i(zanicchi);
|
||
imposta = i.scorpora(imponibile); // ... scorpora imposta dall'imponibile
|
||
}
|
||
|
||
TClinton conto(row, TRUE);
|
||
int newpos = clint2pos(conto, 'I'); // Riga in cui andra' l'imponibile
|
||
|
||
const bool detrarre = detraibile(row); // Determina se IVA detraibile
|
||
|
||
// Calcola riga causale col conto opportuno
|
||
const int ri = detrarre ? RIGA_IVA_DETRAIBILE : RIGA_IVA_NON_DETRAIBILE;
|
||
TBill contoiva; cau.bill(ri, contoiva);
|
||
|
||
if (!detrarre && !contoiva.ok()) // Se non c'e' il conto IVA indetraibile ...
|
||
{ // ... somma imponibile e imposta
|
||
imponibile += imposta;
|
||
imposta = ZERO;
|
||
}
|
||
|
||
TImporto newimp = a.real2imp(imponibile, 'I');
|
||
newimp.normalize();
|
||
|
||
// Aggiorna conto sulla riga contabile
|
||
if (newpos < 0)
|
||
{
|
||
TString saved_descr;
|
||
if (delimp >= 0)
|
||
{
|
||
TSheet_field& s = a.cgs();
|
||
saved_descr = s.row(delimp).get(8); // Memorizza vecchia descrizione
|
||
a.reset_cgs_row(delimp); // Cancella vecchia riga
|
||
if (deliva > delimp) deliva--;
|
||
}
|
||
|
||
if (conto.ok() && !newimp.is_zero()) // Se c'e' imponibile ...
|
||
{ // crea una nuova riga contabile
|
||
if (saved_descr.blank())
|
||
saved_descr = cau.desc_agg(2);
|
||
newpos = a.set_cgs_row(-1, newimp, conto, saved_descr, 'I', conto.commessa(), conto.fase());
|
||
}
|
||
}
|
||
else
|
||
{
|
||
const bool empty = a.add_cgs_imp(newpos, newimp);
|
||
if (empty) // Se la riga si e' azzerata ...
|
||
{ // ... cancellala
|
||
a.reset_cgs_row(newpos);
|
||
newpos = -1;
|
||
}
|
||
else
|
||
{
|
||
if (delimp >= 0 && delimp != newpos)
|
||
{
|
||
a.reset_cgs_row(delimp); // Cancella vecchia riga
|
||
if (deliva > delimp) deliva--;
|
||
}
|
||
}
|
||
}
|
||
oldimp = newimp;
|
||
oldpos = newpos;
|
||
|
||
// Aggiorna conto IVA sulla riga contabile
|
||
|
||
const char tipod = detrarre ? 'D' : 'N';
|
||
int newposiva = type2pos(tipod);
|
||
|
||
if (deliva >= 0 && newposiva != deliva) // E' cambiato il tipo d'imposta
|
||
a.reset_cgs_row(deliva); // Azzera il vecchio tipo se necessario
|
||
|
||
TImporto newiva = a.real2imp(imposta, 'I');
|
||
|
||
newiva.normalize();
|
||
if (newposiva < 0)
|
||
{
|
||
if (!imposta.is_zero()) // Se c'e' imposta ...
|
||
{ // ... crea nuova riga per l'IVA
|
||
const TString d(cau.desc_agg(ri));
|
||
newposiva = a.set_cgs_row(-1, newiva, contoiva, d, tipod);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
const bool empty = a.add_cgs_imp(newposiva, newiva);
|
||
if (empty) // Se l'imposta si e' azzerata ...
|
||
{
|
||
a.reset_cgs_row(newposiva); // ... cancellala
|
||
newposiva = -1;
|
||
}
|
||
}
|
||
|
||
oldiva = newiva;
|
||
oldposiva = newposiva;
|
||
|
||
TMask& m = a.curr_mask();
|
||
if (r == 0) // Se cambio la prima riga ...
|
||
{
|
||
a.add_cgs_tot(m); // ... ricalcola conti e imponibili
|
||
}
|
||
else
|
||
{
|
||
a.calcola_saldo(); // Calcola sbilancio
|
||
a.calcola_imp(); // Calcola imponibili
|
||
}
|
||
|
||
if (a.is_fattura() && m.insert_mode())
|
||
{
|
||
TPagamento& pag = a.pagamento();
|
||
const TValuta cambio(m, SK_VALUTA, SK_DATACAMBIO, SK_CAMBIO, SK_CONTROEURO);
|
||
const bool inv = cambio.in_valuta();
|
||
real imposta, imponibile;
|
||
if (inv)
|
||
{
|
||
const real il(m.get(F_IMPOSTE));
|
||
imposta = cambio.lit2val(il);
|
||
imponibile = m.get_real(SK_TOTDOCVAL) - imposta;
|
||
}
|
||
else
|
||
{
|
||
imposta = m.get_real(F_IMPOSTE);
|
||
imponibile = m.get_real(F_TOTALE) - imposta;
|
||
}
|
||
imposta.round(pag.round(inv)); imponibile.round(pag.round(inv));
|
||
real pimposta(pag.imposta(inv)); real pimponibile(pag.imponibile(inv));
|
||
pimposta.round(pag.round(inv)); pimponibile.round(pag.round(inv));
|
||
|
||
if (pimposta != imposta || pimponibile != imponibile)
|
||
a.set_scadenze(m); // Ricalcola rate
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
// Handler dello sheet
|
||
// Certified 99%
|
||
bool TPrimanota_application::iva_handler(TMask_field& f, KEY k)
|
||
{
|
||
if ((k == K_TAB && !f.mask().is_running()) || k == K_ENTER)
|
||
{
|
||
const TCurrency imp(app().calcola_imp());
|
||
if (k == K_ENTER)
|
||
{
|
||
const TCurrency tot(app().totale_documento());
|
||
if (imp != tot)
|
||
{
|
||
const TString t(tot.string(TRUE));
|
||
const TString i(imp.string(TRUE));
|
||
return error_box(FR("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);
|
||
}
|
||
|
||
TSheet_field& iva = app().ivas();
|
||
for (int i = 0; i < iva.items(); i++)
|
||
{
|
||
TToken_string& row = iva.row(i);
|
||
const real im(row.get(0));
|
||
if (!im.is_zero())
|
||
{
|
||
const TFixed_string codiva = row.get(1);
|
||
if (codiva.blank())
|
||
return error_box(FR("Il codice IVA della riga %d e' obbligatorio"), i+1);
|
||
|
||
TBill c(row, 5, 0x1);
|
||
if (!c.ok() || !c.find())
|
||
return error_box(FR("Il conto della riga iva %d e' errato o incompleto"), i+1);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
bool TPrimanota_application::cg_tipo_handler(TMask_field& f, KEY key)
|
||
{
|
||
if (key == K_TAB && f.focusdirty() || key == K_ENTER)
|
||
{
|
||
TMask& m = f.mask();
|
||
const bool on = f.get().blank() && m.field(CG_SOTTOCONTO).active();
|
||
if (!on)
|
||
{
|
||
m.reset(CG_COMMESSA);
|
||
m.reset(CG_FASE);
|
||
}
|
||
m.enable(CG_COMMESSA, on);
|
||
m.enable(CG_FASE, on);
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
// Il gruppo non possiede una ricerca propria per cui se viene variato richiama
|
||
// quella del conto.
|
||
bool TPrimanota_application::cg_gruppo_handler(TMask_field& f, KEY key)
|
||
{
|
||
if (key == K_TAB && f.focusdirty())
|
||
{
|
||
TEdit_field& conto = f.mask().efield(f.dlg()+1);
|
||
const TRectype& curr = conto.browse()->cursor()->curr();
|
||
if (curr.get(RMV_GRUPPO) != f.get()) // Se non e' gia' posizionato ...
|
||
conto.check(RUNNING_CHECK); // ... forza ricerca sul conto
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
bool TPrimanota_application::cg_conto_handler(TMask_field& f, KEY key)
|
||
{
|
||
bool ok = TRUE;
|
||
|
||
if (key == K_TAB)
|
||
{
|
||
TMask& m = f.mask();
|
||
if (m.field(CG_SOTTOCONTO).active()) // Controlla se sottoconto acceso
|
||
{
|
||
const char cf = m.get(CG_TIPO)[0]; // Tipo conto
|
||
const bool enc = cf <= ' '; // Commessa ammessa per conti normali
|
||
if (!enc)
|
||
{
|
||
m.reset(CG_COMMESSA);
|
||
m.reset(CG_FASE);
|
||
}
|
||
m.enable(CG_COMMESSA, enc);
|
||
m.enable(CG_FASE, enc);
|
||
}
|
||
}
|
||
if (key == K_ENTER)
|
||
{
|
||
TMask& m = f.mask();
|
||
if (m.get(CG_ROWTYPE)[0] == 'T' && !app().causale().corrispettivi())
|
||
{
|
||
const char tipo = app().clifo(); // Tipo conto richiesto dal movimento
|
||
char cf = m.get(f.dlg()-2)[0];
|
||
if (cf < ' ') cf = ' '; // Tipo conto della riga
|
||
if (cf != tipo) // Incongruenza!
|
||
{
|
||
const char* d = tipo == 'C' ? TR("clienti") : TR("fornitori");
|
||
ok = f.error_box(FR("La riga totale richiede un conto %s."), d);
|
||
}
|
||
}
|
||
}
|
||
|
||
return ok;
|
||
}
|
||
|
||
// Gestore del sottoconto dello sheet IVA
|
||
// Attenzione questo handler e' agganciato anche alla descrizione del sottoconto
|
||
bool TPrimanota_application::iva_sottoconto_handler(TMask_field& f, KEY key)
|
||
{
|
||
if (!suspended_handler(f, key))
|
||
return FALSE;
|
||
|
||
TMask& m = f.mask();
|
||
|
||
if (key == K_TAB && f.dirty())
|
||
{
|
||
const TEdit_field& e = (const TEdit_field&)f;
|
||
const TRectype& piano = e.browse()->cursor()->curr();
|
||
int spric = piano.get_int("TIPOSPRIC");
|
||
|
||
if (app().iva() == iva_vendite)
|
||
{
|
||
const TCausale& caus = app().causale();
|
||
if (spric == 2 || spric == 3)
|
||
{
|
||
const TString& td = caus.tipo_doc();
|
||
if (td == "FV" || td == "NC" || td == "ND")
|
||
spric = 4;
|
||
}
|
||
}
|
||
TString16 s; if (spric > 0) s << spric;
|
||
m.set(105, s, TRUE); // Setta il campo spesa-ricavo della riga IVA
|
||
}
|
||
|
||
if (!f.empty() && (key == K_ENTER || (key == K_TAB && f.dirty())))
|
||
{
|
||
TEdit_field& cdc = m.efield(111);
|
||
if (cdc.active() && cdc.empty())
|
||
{
|
||
TBill zio; zio.get(m, 107, 108, 109);
|
||
if (key == K_TAB)
|
||
{
|
||
TString80 cms, fas;
|
||
if (zio.default_cdc(cms, fas))
|
||
{
|
||
m.set(111, cms, 0x2);
|
||
m.set(112, fas, 0x2);
|
||
|
||
}
|
||
}
|
||
TToken_string k = zio.string();
|
||
const TRectype& pc = cache().get(LF_PCON, k);
|
||
if (key == K_ENTER && cdc.empty() && pc.get_bool(PCN_CMSNEEDED))
|
||
{
|
||
k.replace(k.separator(), ' ');
|
||
return cdc.error_box(FR("Il conto %s richiede che sia specificato il codice CDC/Commessa"),
|
||
(const char*)k);
|
||
}
|
||
}
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
bool TPrimanota_application::cg_sottoconto_handler(TMask_field& f, KEY k)
|
||
{
|
||
if (!suspended_handler(f, k))
|
||
return FALSE;
|
||
|
||
if (!f.empty() && (k == K_ENTER || (k == K_TAB && f.dirty())))
|
||
{
|
||
TMask& m = f.mask();
|
||
TEdit_field& cdc = m.efield(CG_COMMESSA);
|
||
if (cdc.active() && cdc.empty())
|
||
{
|
||
TBill zio; zio.get(m, CG_GRUPPO, CG_CONTO, CG_SOTTOCONTO);
|
||
TToken_string key = zio.string();
|
||
const TRectype& pc = cache().get(LF_PCON, key);
|
||
if (k == K_TAB)
|
||
{
|
||
m.set(CG_COMMESSA, pc.get(PCN_CODCMS), 0x2);
|
||
m.set(CG_FASE, pc.get(PCN_FASCMS), 0x2);
|
||
|
||
}
|
||
if (k == K_ENTER && cdc.empty() && pc.get_bool(PCN_CMSNEEDED))
|
||
{
|
||
key.replace(key.separator(), ' ');
|
||
return cdc.error_box(FR("Il conto %s richiede che sia specificato il codice CDC/Commessa"),
|
||
(const char*)key);
|
||
}
|
||
}
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
bool TPrimanota_application::sheet_clifo_handler(TMask_field& f, KEY k)
|
||
{
|
||
if (!suspended_handler(f, k))
|
||
return FALSE;
|
||
|
||
if (k == K_TAB || k == K_ENTER)
|
||
{
|
||
const long codice = atol(f.get());
|
||
if (codice > 0L)
|
||
{
|
||
TMask& m = f.mask();
|
||
const short cid = 100 + (f.dlg() % 100) -1;
|
||
const short gid = cid-1;
|
||
const int conto = m.get_int(cid);
|
||
const int gruppo = m.get_int(gid);
|
||
if ((k == K_TAB && f.focusdirty()) || (gruppo == 0 && conto == 0))
|
||
{
|
||
TBill c(0, 0, codice, f.dlg() > 300 ? 'F' : 'C');
|
||
c.find(); // Carica gruppo e conto
|
||
if (c.ok())
|
||
{
|
||
m.set(gid-1, c.tipo() == 'C' ? "C" : "F");
|
||
m.set(gid, c.gruppo());
|
||
m.set(cid, c.conto());
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Handlers dei campi della testata
|
||
///////////////////////////////////////////////////////////
|
||
|
||
// Handler of the F_NUMREG field on the query mask
|
||
// Certified 99%
|
||
bool TPrimanota_application::num_handler(TMask_field& f, KEY key)
|
||
{
|
||
if (key == K_TAB && f.to_check(key, TRUE))
|
||
{
|
||
TMask& m = f.mask();
|
||
TPrimanota_application& a = app();
|
||
|
||
if (a.autodeleting() == 0x3)
|
||
return TRUE; // Non effettuare controlli inutili in cancellazione
|
||
|
||
a._skip_giornale_check = FALSE;
|
||
a._skip_bollato_check = FALSE;
|
||
|
||
const TRectype& mov = cache().get(LF_MOV, f.get());
|
||
if (!mov.empty())
|
||
{
|
||
bool ok = TRUE;
|
||
|
||
if (mov.get_bool(MOV_STAMPATO))
|
||
{
|
||
ok = f.yesno_box(TR("Il movimento e' gia' stato stampato sul libro giornale:\n"
|
||
"si desidera continuare ugualmente?"));
|
||
a._skip_giornale_check = ok;
|
||
}
|
||
|
||
if (ok && mov.get_bool(MOV_REGST))
|
||
{
|
||
ok = f.yesno_box(TR("Il movimento e' gia' stato stampato sul bollato:\n"
|
||
"si desidera continuare ugualmente?"));
|
||
a._skip_bollato_check = ok;
|
||
}
|
||
|
||
if (ok && mov.get_bool(MOV_INVIATO))
|
||
{
|
||
ok = f.yesno_box(TR("Il movimento e' stato inviato ad un'altra contabilita':\n"
|
||
"si desidera continuare ugualmente?"));
|
||
}
|
||
|
||
if (ok)
|
||
{
|
||
// Riempie a mano i campi necessari nel caso non sia stato usata la ricerca F9
|
||
m.set(F_DATAREG, mov.get(MOV_DATAREG), TRUE);
|
||
// DATACOMP new way
|
||
// m.set(F_DATACOMP, mov.get("DATACOMP"), TRUE);
|
||
m.set(F_CODCAUS, mov.get(MOV_CODCAUS));
|
||
|
||
f.set_focusdirty(FALSE);
|
||
ok = m.stop_run(K_AUTO_ENTER);
|
||
}
|
||
else
|
||
{
|
||
m.reset(F_NUMREG);
|
||
if (a.lnflag())
|
||
m.stop_run(K_FORCE_CLOSE);
|
||
}
|
||
return ok;
|
||
}
|
||
}
|
||
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)
|
||
{
|
||
const TMask& m = f.mask();
|
||
if (!m.is_running()) return TRUE;
|
||
|
||
if (f.to_check(key))
|
||
{
|
||
const TString cau = f.get();
|
||
const int ann = m.get_int(F_ANNOIVA);
|
||
|
||
const TipoIVA i = app().cau2IVA(cau, ann); // Cerca causale e suo tipo
|
||
if (i != iva_errata)
|
||
return suspended_handler(f, key); // Controlla sospensione
|
||
else
|
||
return error_box(TR("Causale non presente in archivio"));
|
||
}
|
||
|
||
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 TString cau(f.get());
|
||
const TCausale c(cau, ann);
|
||
if (!c.ok()) return FALSE;
|
||
|
||
ok = app().causale().similar(c);
|
||
if (!ok)
|
||
return FALSE; // L'errore viene gia' segnalato dalla similar
|
||
if (key == K_TAB)
|
||
{
|
||
app().read_caus(cau, ann);
|
||
app().cgs().force_update();
|
||
}
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
// Handler of the F_DATAREG field
|
||
// Certified 70%
|
||
bool TPrimanota_application::datareg_handler(TMask_field& f, KEY key)
|
||
{
|
||
bool ok = TRUE;
|
||
TMask& m = f.mask();
|
||
|
||
//if ((key == K_TAB && m.is_running() ) || key == K_ENTER)
|
||
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(TR("La data dell'operazione e' superiore quella di sistema"));
|
||
|
||
TPrimanota_application& a = app();
|
||
|
||
const int ae = a._esercizi.date2esc(dr); // Codice esercizio
|
||
if (ae <= 0)
|
||
return f.error_box(TR("La data dell'operazione non appartiene a nessun esercizio"));
|
||
|
||
TLibro_giornale& gio = a.giornale();
|
||
const int ar = dr.year(); // Anno per registri
|
||
if (m.query_mode() || gio.year() != ar)
|
||
{
|
||
ok = gio.read(ar);
|
||
if (!ok)
|
||
return f.error_box(FR("Non esiste il libro giornale del %d"), ar);
|
||
}
|
||
else
|
||
ok = TRUE;
|
||
|
||
if (key == K_ENTER || f.focusdirty())
|
||
{
|
||
const long numreg = m.get_long(F_NUMREG);
|
||
const bool error = numreg == 0 || numreg > a._lastreg;
|
||
|
||
if (key != K_ENTER && !a._skip_giornale_check)
|
||
{
|
||
if (dr < gio.last_print())
|
||
{
|
||
f.error_box(FR("La data dell'operazione e' antecedente al %s,\n"
|
||
"ultima stampa del libro giornale del %d"),
|
||
gio.last_print().string(), ar);
|
||
if (error) return FALSE;
|
||
}
|
||
if (key == K_TAB && dr < gio.last_reg())
|
||
f.warning_box(FR("La data dell'operazione e' antecedente al %s,\n"
|
||
"ultima registrazione sul libro giornale del %d"),
|
||
gio.last_reg().string(), ar);
|
||
}
|
||
|
||
if (m.query_mode())
|
||
a.read_caus(m.get(F_CODCAUS), ar);
|
||
|
||
TRegistro& reg = a.causale().reg();
|
||
const TString codreg(reg.name());
|
||
if (codreg.not_empty())
|
||
{
|
||
if (reg.year() != ar)
|
||
{
|
||
const bool ok = reg.read(codreg, ar);
|
||
if (!ok) return FALSE;
|
||
a.read_caus(NULL, 0);
|
||
if (a.iva() != nessuna_iva)
|
||
m.field(F_CODREG).on_hit();
|
||
}
|
||
|
||
if (!a._skip_bollato_check)
|
||
{
|
||
if (dr < reg.last_print())
|
||
{
|
||
f.error_box(FR("La data dell'operazione e' antecedente al %s,\n"
|
||
"ultima stampa del registro '%s' del %d"),
|
||
reg.last_print().string(), (const char*)codreg, ar);
|
||
if (error) return FALSE;
|
||
}
|
||
if (f.dirty() && dr < reg.last_reg())
|
||
f.warning_box(FR("La data dell'operazione e' antecedente al %s,\n"
|
||
"ultima registrazione sul registro '%s' del %d"),
|
||
reg.last_reg().string(), (const char*)codreg, ar);
|
||
}
|
||
|
||
if (reg.iva() != nessuna_iva && a._rel->controlla_liquidazione(dr, reg) == TRUE)
|
||
{
|
||
const char* const mese = itom(dr.month());
|
||
f.warning_box(FR("La liquidazione IVA relativa al mese di %s e' gia' stata calcolata"), mese);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
// Handler of the F_DATACOMP field on the modify mask
|
||
// Certified 90%
|
||
bool TPrimanota_application::datacomp_handler(TMask_field& f, KEY key)
|
||
{
|
||
TMask& m = f.mask();
|
||
|
||
if (key == K_TAB || key == K_ENTER)
|
||
{
|
||
const TDate dr(m.get(F_DATAREG)); // Data operazione
|
||
|
||
TString16 datacomp = f.get();
|
||
if (datacomp.empty())
|
||
{
|
||
datacomp = dr.string();
|
||
// DATACOMP new way
|
||
if (key == K_ENTER)
|
||
f.set(datacomp);
|
||
}
|
||
const TDate dc(datacomp); // Data di competenza
|
||
TEsercizi_contabili& esc = app()._esercizi;
|
||
const int ae = esc.date2esc(dc); // Esercizio corrispondente
|
||
|
||
const char* data = TR("La data del 74/ter");
|
||
if (f.dlg() == F_DATACOMP)
|
||
{
|
||
m.set(F_ANNOES, ae, TRUE); // Aggiorna anno esercizio in entrambe le pagine
|
||
data = TR("La data di competenza");
|
||
|
||
if (dc > dr)
|
||
{
|
||
bool ok = FALSE;
|
||
const TString& ca = m.get(F_CODCAUS);
|
||
if (ca.not_empty()) // Controlla ratei e risconti
|
||
{
|
||
TConfig ini(CONFIG_DITTA, "cg");
|
||
const TString& ra = ini.get("RrCcRa");
|
||
const TString& ri = ini.get("RrCcRi");
|
||
ok = (ca == ra) || (ca == ri);
|
||
}
|
||
if (!ok)
|
||
return f.error_box("La data di competenza non pu<70> superare la data di registrazione");
|
||
}
|
||
}
|
||
|
||
if (ae)
|
||
{
|
||
const int ar = esc.date2esc(dr); // Esercizio in corso
|
||
const int pr = esc.pred(ar); // Esercizio precedente
|
||
if (ae != ar && ae != pr)
|
||
{
|
||
TString e(80);
|
||
e.format(FR("%s deve appartenere all'esercizio %d"), data, ar);
|
||
if (pr > 0) e << TR(" o all'esercizio ") << pr;
|
||
return f.error_box(e);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (m.is_running())
|
||
return f.error_box(FR("%s non appartiene a nessun esercizio"), data);
|
||
}
|
||
}
|
||
|
||
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;
|
||
|
||
const TDate dr(f.mask().get(F_DATAREG)); // Data operazione
|
||
const TDate d74(f.get()); // Data 74/ter
|
||
if (d74 > dr)
|
||
return TRUE;
|
||
|
||
if (d74.year() < dr.year()-1)
|
||
return error_box(FR("La data 74/ter non puo' essere antecedente all'anno %d"), dr.year()-1);
|
||
|
||
const TLibro_giornale g(d74.year());
|
||
if (!g.ok())
|
||
return error_box(TR("La data 74/ter non appartiene ad un esercizio valido"));
|
||
|
||
if (d74 < g.last_print())
|
||
{
|
||
const char* lp = g.last_print().string();
|
||
return f.error_box(FR("La data 74/ter e' antecedente al %s,\n"
|
||
"data di stampa del libro giornale del %d"), lp, g.year());
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
bool TPrimanota_application::numdoc_handler(TMask_field& f, KEY key)
|
||
{
|
||
if (f.to_check(key, TRUE))
|
||
{
|
||
TMask& m = f.mask();
|
||
if (key == K_TAB && m.insert_mode() && app().is_saldaconto())
|
||
{
|
||
if (!f.empty() && !app().npart_is_prot()) // Copiare numero documento nel numero partita?
|
||
{
|
||
if (m.field(F_NUMRIF).active() && m.get(F_NUMRIF).blank())
|
||
m.set(F_NUMRIF, f.get(), TRUE);
|
||
}
|
||
}
|
||
}
|
||
|
||
// Controllo documenti duplicati
|
||
if (key == K_ENTER && !f.empty() && app().iva() == iva_acquisti)
|
||
{
|
||
TMask& m = f.mask();
|
||
|
||
const int annodoc = m.get_date(F_DATADOC).year();
|
||
const long fornitore = m.get_long(F_FORNITORE);
|
||
if (annodoc > 0 && fornitore > 0)
|
||
{
|
||
// SELECT NUMREG,DATAREG,DATADOC,NUMDOC FROM MOV
|
||
// WHERE TIPO='F' AND CODCF=F_FORNITORE AND
|
||
// NUMDOC=F_NUMDOC AND DATAREG>=F_DATADOC AND NUMREG<>F_NUMREG
|
||
|
||
TString filter;
|
||
filter << MOV_NUMDOC << "=\"" << f.get() << '"';
|
||
if (m.edit_mode())
|
||
{
|
||
filter.insert("(");
|
||
filter << ")&&(" << MOV_NUMREG << "!=\"" << m.get(F_NUMREG) << "\")";
|
||
}
|
||
|
||
TRelation rel(LF_MOV);
|
||
TRectype& rec = rel.curr();
|
||
|
||
TRectype recfrom(rec);
|
||
recfrom.put(MOV_TIPO, "F");
|
||
recfrom.put(MOV_CODCF, fornitore);
|
||
recfrom.put(MOV_DATAREG, TDate(1, 1, annodoc));
|
||
|
||
TRectype recto(recfrom);
|
||
recto.put(MOV_DATAREG, TDate(31, 12, annodoc+1));
|
||
|
||
TCursor cur(&rel, filter, 3, &recfrom, &recto);
|
||
const TRecnotype items = cur.items();
|
||
cur.freeze();
|
||
for (cur = 0; cur.pos() < items; ++cur)
|
||
{
|
||
const int ad = rec.get_date(MOV_DATADOC).year();
|
||
if (ad == annodoc)
|
||
return yesno_box("Il documento %d / %s e' gia' stato inserito con la registrazione %ld\nSi desidera continuare ugualmente?",
|
||
annodoc, (const char*)f.get(), rec.get_long(MOV_NUMREG));
|
||
}
|
||
}
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
bool TPrimanota_application::datadoc_handler(TMask_field& f, KEY key)
|
||
{
|
||
TMask& m = f.mask();
|
||
|
||
if (key == K_TAB && f.to_check(key, TRUE) && app().is_saldaconto())
|
||
{
|
||
const TDate dd(f.get()); // Fattura o nota credito
|
||
if (dd.ok())
|
||
{
|
||
if (m.insert_mode() && m.field(F_ANNORIF).active() && m.get(F_ANNORIF).empty())
|
||
m.set(F_ANNORIF, dd.year()); // copia anno documento
|
||
|
||
TPrimanota_application& a = app();
|
||
if (a.is_fattura())
|
||
{
|
||
if (m.insert_mode())
|
||
{
|
||
if (m.get_bool(FS_RECALC)) // Evita scancellamenti indesiderati
|
||
a.recalc_scadenze(dd);
|
||
}
|
||
else
|
||
{
|
||
if (a._pag)
|
||
a._pag->set_datadoc(dd);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
bool TPrimanota_application::occas_code_handler(TMask_field& f, KEY key)
|
||
{
|
||
TMask& m = f.mask();
|
||
if (key == K_TAB && (f.dirty() || !m.is_running()))
|
||
{
|
||
const TString& code = f.get();
|
||
if (code.not_empty())
|
||
{
|
||
TRelation occas(LF_OCCAS);
|
||
occas.curr().put("CFPI", code);
|
||
if (occas.read(_isequal) == NOERR)
|
||
{
|
||
m.autoload(occas);
|
||
m.send_key(K_TAB, O_COMUNE); // Forza decodifica comuni
|
||
m.send_key(K_TAB, O_COMUNENAS);
|
||
}
|
||
}
|
||
}
|
||
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)
|
||
{
|
||
const bool corri = causale().corrispettivi();
|
||
const char tipo = corri ? ' ' : app().clifo();
|
||
int gruppo = 0, conto = 0;
|
||
long codice = corri ? 0L : m.get_long(tipo == 'C' ? F_CLIENTE : F_FORNITORE);
|
||
|
||
TSheet_field& ss = cgs();
|
||
const int riga_totale = type2pos('T');
|
||
|
||
// Cerca di preservare il gruppo-conto-sottoconto sulla riga totale
|
||
if (riga_totale >= 0)
|
||
{
|
||
TToken_string& rowt = ss.row(riga_totale);
|
||
|
||
gruppo = rowt.get_int(3);
|
||
conto = rowt.get_int();
|
||
const long oldcode = rowt.get_long();
|
||
|
||
if (corri)
|
||
codice = oldcode; // I corrispettivi non hanno un cliente in testata
|
||
else
|
||
{
|
||
if (m.insert_mode()) // Errore MI3567: se cambio cliente ripesca conto
|
||
{
|
||
if (codice != oldcode) // Se cambia il codice cliente ...
|
||
gruppo = conto = 0; // ... forza il ricalcolo del gruppo-conto
|
||
}
|
||
}
|
||
}
|
||
|
||
TBill nuovo(gruppo, conto, codice, tipo);
|
||
if (!corri && (gruppo == 0 || conto == 0))
|
||
nuovo.find(); // Compila anche gruppo e conto in base al codice clifo
|
||
|
||
if (nuovo.gruppo() == 0 || nuovo.conto() == 0)
|
||
{
|
||
// Se l'utente non ha ancora specificato un conto lo prendo dalla prima riga della causale
|
||
causale().bill(1, nuovo);
|
||
|
||
// Nelle fatture si deve sempre aggiungere il codice clifo (in causale normalmente non c'e')
|
||
if (!corri)
|
||
nuovo.codclifo() = codice;
|
||
}
|
||
|
||
if (riga_totale >= 0)
|
||
{
|
||
TToken_string& row = ss.row(riga_totale);
|
||
const TBill vecchio(row, 2, 0x1);
|
||
if (!vecchio.empty() && nuovo != vecchio) // Se cambio cliente/fornitore
|
||
{
|
||
for (int i = 0; i < ss.items(); i++) if (i != riga_totale)
|
||
{
|
||
TToken_string& r = ss.row(i);
|
||
const TBill tacchia(r, 9, 0x1);
|
||
if (tacchia == vecchio)
|
||
{
|
||
nuovo.add_to(r, 9, 0x3); // Aggiorna contropartite
|
||
ss.force_update(i);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (!_as400)
|
||
{
|
||
// Creazione/Aggiornamento riga totale
|
||
const real tot(m.get(F_TOTALE));
|
||
TString descr;
|
||
if (riga_totale >= 0)
|
||
descr = cgs().row(riga_totale).get(8);
|
||
if (descr.blank())
|
||
descr = m.get(F_DESCR);
|
||
set_cgs_row(riga_totale, real2imp(tot, 'T'), nuovo, descr, 'T');
|
||
}
|
||
|
||
calcola_imp(); // Ricalcola totale IVA
|
||
calcola_saldo(); // Ricalcola sbilanci
|
||
}
|
||
|
||
// 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.active())
|
||
{
|
||
TPrimanota_application& a = app();
|
||
TMask& m = f.mask();
|
||
|
||
if (f.focusdirty() && a.is_nota_credito())
|
||
{
|
||
TPartite_array& p = a.partite();
|
||
|
||
const TPartita* game = p.first();
|
||
if (game != NULL && atol(f.get()) != game->conto().codclifo())
|
||
{
|
||
const bool del = f.yesno_box(TR("Si desidera cancellare i pagamenti effettuati?"));
|
||
if (!del) // Ripristina codice copiandolo dalla prima partita
|
||
{
|
||
TString cod; cod << game->conto().codclifo();
|
||
f.set(cod);
|
||
return TRUE;
|
||
}
|
||
f.set_dirty(); // yesno_box cleared the dirty flag
|
||
a.notify_cgline_deletion(-1);
|
||
}
|
||
}
|
||
|
||
const char cf = a.clifo();
|
||
const long codice = atol(f.get());
|
||
|
||
if (codice == 0)
|
||
{
|
||
m.hide(F_OCCASEDIT); // Spegni bottone occasionali
|
||
m.show(F_STATOPAIV); // Stato partita IVA
|
||
m.show(cf == 'C' ? F_PIVACLIENTE : F_PIVAFORNITORE); // Partita IVA
|
||
m.show(cf == 'C' ? F_COFICLIENTE : F_COFIFORNITORE); // Codice Fiscale
|
||
a.activate_numrif(m, TRUE);
|
||
return TRUE;
|
||
}
|
||
|
||
TRelation cliforel(LF_CLIFO); cliforel.add(LF_CFVEN, "TIPOCF=TIPOCF|CODCF=CODCF");
|
||
TRectype& clifo = cliforel.curr();
|
||
clifo.put(CLI_TIPOCF, cf);
|
||
clifo.put(CLI_CODCF, codice);
|
||
cliforel.read();
|
||
|
||
if (!m.is_running() || f.dirty())
|
||
{
|
||
a._conto_ricavo.set(clifo.get_int(CLI_GRUPPORIC),
|
||
clifo.get_int(CLI_CONTORIC),
|
||
clifo.get_long(CLI_SOTTOCRIC));
|
||
if (a._conto_ricavo.find())
|
||
{
|
||
if (a._conto_ricavo.sospeso())
|
||
{
|
||
f.error_box(TR("Il conto di ricavo e' sospeso"));
|
||
a._conto_ricavo.set(0,0,0);
|
||
}
|
||
}
|
||
|
||
const int alleg = clifo.get_int(CLI_ALLEG);
|
||
TEdit_field& upi = m.efield(F_RIEPILOGO);
|
||
upi.check_type(alleg == 3 ? CHECK_REQUIRED : CHECK_NORMAL);
|
||
|
||
TEdit_field& cp = m.efield(F_CODPAG);
|
||
if ((f.focusdirty() && m.is_running()) || (cp.empty() && !m.is_running()))
|
||
{
|
||
const TString& oldpag = cp.get();
|
||
const TString& s = clifo.get(CLI_CODPAG);
|
||
if (s != oldpag)
|
||
{
|
||
if (cp.active()) // Se il campo F_CODPAG e' attivo
|
||
{
|
||
cp.set(s); // Setta il codice di pagamento sulla maschera
|
||
cp.check(RUNNING_CHECK); // lo decodifica
|
||
cp.on_hit(); // lo ricopia eventualmente a pag.3
|
||
}
|
||
}
|
||
if (cf == 'F' && app().causale().valintra())
|
||
{
|
||
const TString16 valintra(clifo.get("VALINTRA"));
|
||
if (!valintra.empty())
|
||
m.set(F_VALUTAINTRA, valintra, TRUE);
|
||
}
|
||
}
|
||
|
||
if (f.focusdirty() && a.is_saldaconto())
|
||
{
|
||
if (m.field(SK_VALUTA).active() && m.get(SK_VALUTA).empty())
|
||
{
|
||
const TString& valuta = clifo.get(CLI_CODVAL);
|
||
if (valuta.not_empty())
|
||
m.set(SK_VALUTA, valuta, TRUE);
|
||
}
|
||
|
||
if (a.is_fattura())
|
||
{
|
||
const TRectype& clifov = cliforel.curr(LF_CFVEN);
|
||
|
||
if (clifo.get(CLI_CODCAB).not_empty())
|
||
{
|
||
m.set(FS_VSABI, clifo.get(CLI_CODABI));
|
||
m.set(FS_VSCAB, clifo.get(CLI_CODCAB));
|
||
m.send_key(K_TAB, FS_VSCAB);
|
||
}
|
||
if (clifov.get(CFV_CODCABPR).not_empty())
|
||
{
|
||
m.set(FS_NSABI, clifov.get(CFV_CODABIPR));
|
||
m.set(FS_NSCAB, clifov.get(CFV_CODCABPR));
|
||
m.send_key(K_TAB, FS_NSCAB);
|
||
}
|
||
|
||
const TString& agente = clifov.get(CLI_CODAG);
|
||
if (agente.not_empty())
|
||
{
|
||
m.set(FS_AGENTE, agente, TRUE);
|
||
m.send_key(K_TAB, FS_AGENTE);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
const bool occas = clifo.get_bool(CLI_OCCAS);
|
||
m.show(F_OCCASEDIT, occas); // Bottone Dati anagrafici
|
||
m.show(F_STATOPAIV, !occas); // Stato partita IVA
|
||
if (!occas)
|
||
m.set(F_STATOPAIV, clifo.get(CLI_STATOPAIV));
|
||
m.show(cf == 'C' ? F_PIVACLIENTE : F_PIVAFORNITORE, !occas); // Partita IVA
|
||
m.show(cf == 'C' ? F_COFICLIENTE : F_COFIFORNITORE, !occas); // Codice Fiscale
|
||
|
||
if (occas && a.is_fattura() && a.partite().first() != NULL)
|
||
{
|
||
f.warning_box(TR("Attenzione, il saldaconto verra' eliminato!"));
|
||
f.set_dirty(); // warning_box cleans the field!
|
||
}
|
||
a.activate_numrif(m, TRUE);
|
||
|
||
if (f.focusdirty())
|
||
{
|
||
a.add_cgs_tot(m);
|
||
if (occas && a.occas_mask().get(O_CODICE).blank())
|
||
m.send_key(K_SPACE, F_OCCASEDIT); // Lancia maschera occasionali
|
||
}
|
||
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
bool TPrimanota_application::IVA2bill(const TCodiceIVA& iva, TBill& bill)
|
||
{
|
||
const TCausale& cau = causale();
|
||
if (!cau.corrispettivi())
|
||
bill = _conto_ricavo;
|
||
return cau.IVA2bill(iva, bill);
|
||
}
|
||
|
||
|
||
// Handler of the F_CODIVA
|
||
// Certified 99%
|
||
bool TPrimanota_application::main_codiva_handler(TMask_field& f, KEY key)
|
||
{
|
||
if (key == K_TAB && !f.empty())
|
||
{
|
||
if (!suspended_handler(f, key))
|
||
return FALSE;
|
||
|
||
TPrimanota_application& a = app();
|
||
const real imp(a.ivas().row(1).get(0));
|
||
if (imp.is_zero()) // Se il totale documento non e' stato spezzato
|
||
{
|
||
TToken_string& row = a.ivas().row(0);
|
||
|
||
TMask& m = f.mask();
|
||
iva_notify(a.ivas(), 0, K_SPACE);
|
||
|
||
const TCodiceIVA iva(f.get());
|
||
const bool corr = a.causale().corrispettivi();
|
||
const bool acq3 = (a.iva() == iva_acquisti) && (row.get_int(2) == 3);
|
||
|
||
real tot = a.totale_documento(); // Calcola totale documento
|
||
real imposta; // Calcola imposta
|
||
if (!corr && !acq3)
|
||
imposta = iva.scorpora(tot);
|
||
|
||
row.add(tot.string(), 0); // imponibile
|
||
row.add(imposta.string(), 3); // imposta
|
||
|
||
if (iva.codice() != row.get(1))
|
||
{
|
||
row.add(iva.codice(), 1); // Aggiorna codice IVA
|
||
|
||
const int det = iva.detraibilita();
|
||
if (det > 0) row.add(det, 2);
|
||
|
||
TBill bill; // Aggiorna conto della prima riga IVA
|
||
a.IVA2bill(iva, bill);
|
||
bill.add_to(row, 4, 0x7);
|
||
if (bill.tipo() <= ' ' && bill.sottoconto() > 0)
|
||
{
|
||
TString80 cms, fas;
|
||
if (bill.default_cdc(cms, fas))
|
||
{
|
||
row.add(cms, 10); // Cdc/commessa su riga IVA
|
||
row.add(fas, 11); // Fase
|
||
}
|
||
}
|
||
}
|
||
a.ivas().force_update(0);
|
||
|
||
iva_notify(a.ivas(), 0, K_ENTER);
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
// Riempie i campi valuta a zero in base agli altri
|
||
void TPrimanota_application::gioca_cambi(int force)
|
||
{
|
||
TMask& m = curr_mask();
|
||
if (m.get(SK_VALUTA).empty())
|
||
return;
|
||
|
||
const real totale = m.get(F_TOTALE);
|
||
const real totval = m.get(SK_TOTDOCVAL);
|
||
const real cambio = m.get(SK_CAMBIO);
|
||
|
||
if ( (force == 0x1 || totale.is_zero()) && !(totval.is_zero() || cambio.is_zero()) )
|
||
{
|
||
const TValuta cam(m, SK_VALUTA, SK_DATACAMBIO, SK_CAMBIO, SK_CONTROEURO);
|
||
const real new_totale = cam.val2lit(totval);
|
||
if (new_totale != totale)
|
||
m.set(F_TOTALE, new_totale, TRUE);
|
||
}
|
||
|
||
if ( (force == 0x2 || totval.is_zero()) && !(totale.is_zero() || cambio.is_zero()) )
|
||
{
|
||
const TValuta cam(m, SK_VALUTA, SK_DATACAMBIO, SK_CAMBIO, SK_CONTROEURO);
|
||
const real new_totval = cam.lit2val(totale);
|
||
if (new_totval != totval)
|
||
m.set(SK_TOTDOCVAL, new_totval, TRUE);
|
||
}
|
||
|
||
if ( (force == 0x4 || cambio.is_zero()) && !(totale.is_zero() || totval.is_zero()) )
|
||
{
|
||
real new_cambio = totale / totval;
|
||
if (m.id2pos(SK_CONTROEURO) >= 0)
|
||
m.reset(SK_CONTROEURO);
|
||
|
||
exchange_type dummy_contro_euro;
|
||
const real& fc = TCurrency::get_firm_change(dummy_contro_euro);
|
||
if (fc > ZERO)
|
||
new_cambio *= fc;
|
||
|
||
new_cambio.round(6);
|
||
if (new_cambio != cambio)
|
||
m.set(SK_CAMBIO, new_cambio, TRUE);
|
||
}
|
||
}
|
||
|
||
|
||
// Handler of the F_TOTALE
|
||
// Certified 99%
|
||
bool TPrimanota_application::totdoc_handler(TMask_field& f, KEY key)
|
||
{
|
||
bool ok = TRUE;
|
||
TMask& m = f.mask();
|
||
TPrimanota_application& a = app();
|
||
|
||
if (key == K_TAB && f.focusdirty())
|
||
{
|
||
a.gioca_cambi();
|
||
|
||
if (a.iva() != nessuna_iva)
|
||
{
|
||
a.add_cgs_tot(m);
|
||
if (m.insert_mode()) // Se si e' in inserimento provoca ricalcolo
|
||
m.field(F_CODIVA).on_hit(); // dello sheet iva e delle scadenze
|
||
}
|
||
else
|
||
{
|
||
if (a.is_pagamento())
|
||
a.calcola_saldo();
|
||
}
|
||
}
|
||
|
||
if (key == K_ENTER)
|
||
{
|
||
const TCurrency totale(real(f.get()));
|
||
if (totale.get_num().is_zero())
|
||
ok = yesno_box(TR("Totale documento nullo: continuare ugualmente?"));
|
||
|
||
if (ok)
|
||
{
|
||
const TValuta cambio(m, SK_VALUTA, SK_DATACAMBIO, SK_CAMBIO, SK_CONTROEURO);
|
||
if (cambio.in_valuta())
|
||
{
|
||
const real totval(m.get(SK_TOTDOCVAL));
|
||
const TCurrency totlit(cambio.val2lit(totval));
|
||
if (totale != totlit)
|
||
ok = f.yesno_box(FR("Il totale documento dovrebbe essere %s: continuare ugualmente?"),
|
||
totlit.string(TRUE));
|
||
}
|
||
}
|
||
|
||
if (a.iva() == nessuna_iva && a.is_fattura())
|
||
{
|
||
TBill bill;
|
||
const int riga_cf = a.cerca_conto_cf(bill);
|
||
if (riga_cf >= 0)
|
||
{
|
||
TImporto imp = a.get_cgs_imp(riga_cf);
|
||
if (imp.valore() != m.get_real(F_TOTALE))
|
||
ok = f.error_box(FR("Il totale documento non corrisponde alla riga %d:\ndovrebbe essere %s"),
|
||
riga_cf+1, imp.valore().string());
|
||
}
|
||
}
|
||
}
|
||
|
||
return ok;
|
||
}
|
||
|
||
bool TPrimanota_application::totdocval_handler(TMask_field& f, KEY key)
|
||
{
|
||
if (key == K_TAB && f.focusdirty())
|
||
{
|
||
TPrimanota_application& a = app();
|
||
a.gioca_cambi();
|
||
|
||
TMask& m = f.mask();
|
||
if (a.is_fattura() && m.insert_mode())
|
||
a.set_scadenze(m);
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
// Aggiunge o aggiorna la riga delle ritenute fiscali o sociali
|
||
// Certified 99%
|
||
void TPrimanota_application::add_cgs_rit(bool fiscali)
|
||
{
|
||
if (_as400)
|
||
return;
|
||
|
||
TMask& m = curr_mask();
|
||
const real imp(m.get(fiscali ? F_RITFIS : F_RITSOC)); // Determina importo
|
||
|
||
const char tipo = fiscali ? 'F' : 'S';
|
||
const int pos = type2pos(tipo); // Cerca la riga contabile
|
||
if (pos < 0) // Se non c'e' ...
|
||
{
|
||
if (!imp.is_zero()) // ... e l'importo e' valido
|
||
{ // crea una nuova riga di ritenute
|
||
const int riga = fiscali ? RIGA_RITENUTE_FISCALI : RIGA_RITENUTE_SOCIALI;
|
||
TBill conto; causale().bill(riga, conto);
|
||
const TString desc(causale().desc_agg(riga));
|
||
set_cgs_row(-1, real2imp(imp, tipo), conto, desc, tipo);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (imp.is_zero()) // se l'importo e' nullo ...
|
||
reset_cgs_row(pos); // ... azzera la riga contabile
|
||
else // altrimenti ...
|
||
set_cgs_imp(pos, real2imp(imp, tipo)); // ... aggiorna importo
|
||
}
|
||
|
||
if (m.insert_mode())
|
||
m.field(F_CODIVA).on_hit(); // Ricalcola sheet iva e contabile
|
||
else
|
||
app().calcola_saldo(); // Ricalcola solo lo sbilancio
|
||
}
|
||
|
||
// Handler of the F_PROTIVA
|
||
bool TPrimanota_application::protiva_handler(TMask_field& f, KEY key)
|
||
{
|
||
bool ok = TRUE;
|
||
TMask& m = f.mask();
|
||
|
||
if (m.insert_mode())
|
||
{
|
||
if (key == K_ENTER && f.dirty())
|
||
{
|
||
const long protiva = atol(f.get());
|
||
const long protocol = app().causale().reg().protocol() + 1;
|
||
if (protiva != protocol)
|
||
ok = f.yesno_box(FR("Accettare il protocollo IVA fuori sequenza: %ld invece di %ld"),
|
||
protiva, protocol);
|
||
|
||
}
|
||
else
|
||
if (key == K_TAB && m.insert_mode() && app().npart_is_prot() &&
|
||
m.field(F_NUMRIF).active() && m.get(F_NUMRIF).blank())
|
||
{
|
||
const TString& piva = f.get();
|
||
if (piva.not_empty())
|
||
m.set(F_NUMRIF, piva, TRUE);
|
||
}
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
|
||
// 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;
|
||
}
|
||
|
||
HIDDEN void inventa_cambio_intra(TMask& m)
|
||
{
|
||
const TString& codval = m.get(F_VALUTAINTRA);
|
||
if (codval.not_empty() && TCurrency::get_firm_val() != codval)
|
||
{
|
||
TTable cam("CAM");
|
||
cam.put("CODTAB", codval);
|
||
const int err = cam.read(_isgteq);
|
||
bool yes = err != NOERR;
|
||
if (!yes)
|
||
{
|
||
TString16 v = cam.get("CODTAB");
|
||
v.cut(3).rtrim();
|
||
yes = v != codval;
|
||
}
|
||
if (yes)
|
||
m.set(F_CAMBIOINTRA, cache().get("%VAL", codval, "S4"));
|
||
}
|
||
}
|
||
|
||
// Handler of F_CORRLIRE
|
||
// Certified 99%
|
||
bool TPrimanota_application::corrlire_handler(TMask_field& f, KEY key)
|
||
{
|
||
TMask& m = f.mask();
|
||
TMask_field& cv = m.field(F_CORRVALUTA);
|
||
|
||
if (key == K_ENTER && f.get().empty())
|
||
{
|
||
if (!cv.empty())
|
||
{
|
||
cv.set_focusdirty();
|
||
cv.on_hit();
|
||
}
|
||
else
|
||
key = K_F8;
|
||
}
|
||
|
||
if (key == K_F8)
|
||
{
|
||
f.set(m.get(F_IMPONIBILI));
|
||
f.set_dirty();
|
||
cv.set("");
|
||
key = K_TAB;
|
||
}
|
||
if (key == K_TAB && f.focusdirty())
|
||
{
|
||
if (cv.empty())
|
||
{
|
||
if (m.field(F_CAMBIOINTRA).empty())
|
||
inventa_cambio_intra(m);
|
||
const TExchange cambio(m.get(F_VALUTAINTRA), m.get_real(F_CAMBIOINTRA));
|
||
TCurrency imp(real(f.get()));
|
||
imp.change_value(cambio);
|
||
cv.set(imp.get_num().string());
|
||
}
|
||
}
|
||
|
||
if (key == K_ENTER)
|
||
{
|
||
const real im(m.get(F_IMPONIBILI));
|
||
const real cl(f.get());
|
||
if (im != cl)
|
||
{
|
||
const TRectype& rec = cache().get("%VAL", TCurrency::get_firm_val());
|
||
const char* name = (const char*)rec.get("S0");
|
||
warning_box(FR("Il corrispettivo in %s e' diverso dal totale degli imponibili"), name);
|
||
}
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
// Handler of F_CORRVALUTA
|
||
// Certified 99%
|
||
bool TPrimanota_application::corrvaluta_handler(TMask_field& f, KEY key)
|
||
{
|
||
TMask& m = f.mask();
|
||
TMask_field& cl = m.field(F_CORRISPETTIVO);
|
||
|
||
if (key == K_TAB && f.focusdirty())
|
||
{
|
||
if (cl.empty())
|
||
{
|
||
if (m.field(F_CAMBIOINTRA).empty())
|
||
inventa_cambio_intra(m);
|
||
const TExchange cambio(m.get(F_VALUTAINTRA), m.get_real(F_CAMBIOINTRA));
|
||
TCurrency imp(real(f.get()), cambio);
|
||
imp.change_to_firm_val();
|
||
cl.set(imp.get_num().string());
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (key == K_ENTER && f.get().empty())
|
||
{
|
||
cl.set_dirty();
|
||
cl.on_hit();
|
||
}
|
||
}
|
||
return TRUE;
|
||
}
|
||
|
||
bool TPrimanota_application::activate_numrif(TMask& m, bool init_pag)
|
||
{
|
||
bool shown = is_saldaconto(); // Il numero riferimento esiste
|
||
|
||
if (shown)
|
||
{
|
||
if (m.id2pos(F_SOLAIVA) >= 0) // Maschera moviventi IVA
|
||
{
|
||
const bool hide = m.get_bool(F_SOLAIVA) || m.field(F_OCCASEDIT).shown();
|
||
if (hide) shown = FALSE;
|
||
}
|
||
}
|
||
|
||
if (shown != m.field(F_NUMRIF).shown())
|
||
{
|
||
m.show(F_ANNORIF, shown);
|
||
m.show(F_NUMRIF, shown);
|
||
if (shown)
|
||
{
|
||
if (m.get(F_ANNORIF).empty())
|
||
{
|
||
m.set(F_ANNORIF, m.get(F_DATADOC).right(4));
|
||
m.set(F_NUMRIF, m.get(_npart_is_prot ? F_PROTIVA : F_NUMDOC));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
m.reset(F_ANNORIF);
|
||
m.reset(F_NUMRIF);
|
||
}
|
||
}
|
||
|
||
// Gestione pagina 3
|
||
const bool page = shown && is_fattura() && !m.get(F_NUMRIF).blank();
|
||
if (page != m.page_enabled(2))
|
||
{
|
||
m.enable_page(2, page);
|
||
if (page && init_pag && m.is_running())
|
||
{
|
||
if (m.edit_mode())
|
||
{
|
||
const TString16 dt(m.get(F_DATADOC));
|
||
set_pagamento(NULL, dt); // Reset pagamento
|
||
set_totale_pagamento(TRUE);
|
||
}
|
||
else
|
||
set_scadenze(m); // Inizializza pagamento
|
||
}
|
||
}
|
||
|
||
return shown;
|
||
}
|
||
|
||
// Handler del checkbox di movimento di sola IVA
|
||
bool TPrimanota_application::solaiva_handler(TMask_field& f, KEY key)
|
||
{
|
||
TMask& m = f.mask();
|
||
const bool run = m.is_running();
|
||
|
||
if ((key == K_TAB && f.focusdirty()) || !run)
|
||
{
|
||
TPrimanota_application& a = app();
|
||
|
||
bool anchecg = f.get()[0] != 'X';
|
||
bool recalcg = anchecg;
|
||
|
||
if (run && a.is_fattura())
|
||
{
|
||
const TPartita* game = a.partite().first();
|
||
|
||
if (anchecg)
|
||
{
|
||
if (game != NULL)
|
||
{
|
||
m.set(F_ANNORIF, game->anno());
|
||
m.set(F_NUMRIF, game->numero());
|
||
}
|
||
}
|
||
else
|
||
{
|
||
bool del = TRUE;
|
||
if (game != NULL)
|
||
del = f.yesno_box(TR("Si desidera cancellare il saldaconto?"));
|
||
if (!del)
|
||
{
|
||
f.reset();
|
||
anchecg = TRUE;
|
||
recalcg = FALSE;
|
||
}
|
||
}
|
||
a.activate_numrif(m, TRUE);
|
||
}
|
||
|
||
m.show(F_SHEETCG, anchecg);
|
||
m.show(F_DARE, anchecg);
|
||
m.show(F_AVERE, anchecg);
|
||
|
||
if (run && recalcg)
|
||
{
|
||
TSheet_field& iva = a.ivas();
|
||
const int righe = iva.items();
|
||
TProgind pi(righe, TR("Generazione righe contabilita'"), FALSE, TRUE);
|
||
|
||
TSheet_field& cg = a.cgs();
|
||
cg.reset();
|
||
|
||
a.add_cgs_tot(m); // Genera totale documento
|
||
if (m.get(F_RITFIS).not_empty()) a.add_cgs_rit(TRUE); // Genera ritenute fiscali
|
||
if (m.get(F_RITSOC).not_empty()) a.add_cgs_rit(FALSE); // Genera ritenute sociali
|
||
|
||
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(iva, i, K_SPACE); // Simula la creazione di una nuova riga iva
|
||
r = oldrow;
|
||
iva_notify(iva, i, K_ENTER);
|
||
}
|
||
pi.setstatus(i+1);
|
||
}
|
||
a.fill_sheet(m); // Aggiunge righe vuote
|
||
cg.force_update();
|
||
m.set_focus(); // Ripristina il focus al campo (a causa della progind)
|
||
}
|
||
}
|
||
return TRUE;
|
||
} |