campo-sirio/cg/cg2102.cpp

3185 lines
92 KiB
C++
Raw Normal View History

#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 + CENTO);
imposta.ceil();
if (imponibile.sign() < 0) imposta = -imposta;
}
else
{ // Gestione Euro
imposta = imponibile * percent / (percent + CENTO);
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%
Patch level : 2.0 604 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
2003-10-17 08:28:05 +00:00
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 100%
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 100%
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()
{
const bool pagamento = is_pagamento();
const long numreg = curr_mask().get_long(F_NUMREG);
bool rowtypes_present = false;
TSheet_field& s = cgs();
TString_array& rows = s.rows_array();
for (int i = rows.items()-1; i >= 0; i--)
{
TToken_string& r = rows.row(i);
const char rt = row_type(r);
rowtypes_present |= (rt > ' ');
if (can_remove(r))
{
bool ok = TRUE;
if (pagamento && rt == 'K')
{
ok = !partite().utilizzata(numreg, i+1);
if (ok)
cg_notify(s, i, K_DEL);
}
if (ok)
rows.destroy(i, TRUE);
}
}
if (!pagamento && rowtypes_present) // Il pagamento e' gia' ordinato
rows.TArray::sort(compare_rows); // Pack and sort array
}
bool TPrimanota_application::ci_sono_importi() const
{
Patch level : 2.0 604 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
2003-10-17 08:28:05 +00:00
const int rows = cgs().items();
for (int i = 0; i < rows; i++)
{
Patch level : 2.0 604 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
2003-10-17 08:28:05 +00:00
const TImporto imp = get_cgs_imp(i);
if (!imp.is_zero())
return true;
}
Patch level : 2.0 604 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
2003-10-17 08:28:05 +00:00
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;
Patch level : 2.0 604 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
2003-10-17 08:28:05 +00:00
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;
int i;
for (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)
{
TMask& m = curr_mask();
TSheet_field& sheet = m.sfield(F_SHEETCG);
TToken_string row = sheet.row(r);
TBill bill; bill.get(row, 2, 0x1);
if (bill.ok())
{
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_real(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);
TImporto imp = real2imp(tot, 'T');
imp.normalize();
set_cgs_row(riga_totale, imp, 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_real(F_TOTALE);
const real totval = m.get_real(SK_TOTDOCVAL);
const real cambio = m.get_real(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();
Patch level : 2.0 604 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
2003-10-17 08:28:05 +00:00
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));
}
}
Patch level : 2.0 604 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
2003-10-17 08:28:05 +00:00
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)
{
// Il numero riferimento esiste
bool shown = is_saldaconto() && (is_fattura() || is_nota_credito());
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.field(F_ANNORIF).empty())
{
m.set(F_ANNORIF, m.get_date(F_DATADOC).year());
const bool use_protiva = _npart_is_prot && m.id2pos(F_PROTIVA) > 0;
m.set(F_NUMRIF, m.get(use_protiva ? 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 TString& 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;
}