Files correlati : cg2.exe ve0.exe Il campo reverse charge delle righe IVA non era inizializzato correttamente dalla contabilizzazione delle vendite. Interno Da controllare una vendita un acquistoe un acquisto reverse charge.
4545 lines
130 KiB
C++
Executable File
4545 lines
130 KiB
C++
Executable File
#include <automask.h>
|
||
#include <colors.h>
|
||
#include <dongle.h>
|
||
#include <execp.h>
|
||
#include <msksheet.h>
|
||
#include <progind.h>
|
||
#include <tabutil.h>
|
||
#include <toolfld.h>
|
||
#include <urldefid.h>
|
||
#include <utility.h>
|
||
#include <validate.h>
|
||
|
||
#include "cg2100.h"
|
||
#include "cg2102.h"
|
||
#include "cg21sld.h"
|
||
#include "cglib.h"
|
||
|
||
#include <clifo.h>
|
||
#include <cfven.h>
|
||
#include <pconti.h>
|
||
#include <doc.h>
|
||
#include <occas.h>
|
||
#include "../fp/fplib.h"
|
||
#include "../f1/f1lib.h"
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Funzioni di decodifica/calcolo
|
||
///////////////////////////////////////////////////////////
|
||
|
||
// Determina il tipo di una riga contabile in formato TToken_string
|
||
char TPrimanota_application::row_type(const TToken_string& s)
|
||
{
|
||
char t = cgrowtype_contabile;
|
||
|
||
if (s.full())
|
||
{
|
||
s.get(cid2index(CG_ROWTYPE), t);
|
||
if (!((t >= 'A' && t <= 'Z')||((t >= '0' && t <= '9')))) // is not alphanumeric?
|
||
t = cgrowtype_contabile;
|
||
}
|
||
return t;
|
||
}
|
||
|
||
// 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 TString4 _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;
|
||
const 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)
|
||
{
|
||
const int dec = TCurrency::get_firm_dec();
|
||
real 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, ritenute fiscali e reverse charge
|
||
real TPrimanota_application::totale_documento()
|
||
{
|
||
const TMask& m = curr_mask();
|
||
real tot = m.get(F_TOTALE); // Legge totale
|
||
|
||
tot += m.get_real(F_RITFIS); // Somma ritenute fiscali
|
||
// tot += m.get_real(F_REVCHARGE); // Somma eventuale reverse charge
|
||
const real ritsoc = m.get_real(F_RITSOC);
|
||
|
||
if (!ritsoc.is_zero())
|
||
{
|
||
const bool swapt = test_swap(false); // Totale invertito ?
|
||
const bool swaps = test_swap(true); // Ritenute sociali invertite ?
|
||
if (swapt ^ swaps) // Somma ritenute sociali con segno
|
||
tot -= ritsoc;
|
||
else
|
||
tot += ritsoc;
|
||
}
|
||
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' <20> sospeso e non puo' essere utilizzato"), sf);
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////
|
||
// Funzioni di ricerca
|
||
///////////////////////////////////////////////////////////
|
||
|
||
int TPrimanota_application::type2pos(char tipo)
|
||
{
|
||
TString_array& a = app().cgs().rows_array();
|
||
|
||
FOR_EACH_ARRAY_ROW(a, i, s)
|
||
{
|
||
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& a = app().cgs().rows_array();
|
||
FOR_EACH_ARRAY_ROW(a, i, s)
|
||
{
|
||
const char t = row_type(*s);
|
||
|
||
if (t == tipo)
|
||
{
|
||
const TBill c(*s, 3, 0x0);
|
||
|
||
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& a = app().cgs().rows_array();
|
||
TBill c; // Conto corrente (Buona questa!)
|
||
FOR_EACH_ARRAY_ROW(a, i, r)
|
||
{
|
||
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_EACH_ARRAY_ROW(rows, i, row)
|
||
{
|
||
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");
|
||
return m->sfield(F_SHEETCG);
|
||
}
|
||
|
||
|
||
// 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
|
||
{
|
||
TImporto importo;
|
||
|
||
TSheet_field& s = cgs();
|
||
if (n >= 0 && n < s.items())
|
||
{
|
||
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 = false;
|
||
|
||
switch (row_type)
|
||
{
|
||
case cgrowtype_ritsoc:
|
||
dare = causale().sezione_ritsoc() == 'D';
|
||
break;
|
||
case cgrowtype_revcharge:
|
||
dare = causale().sezione_revcharge() == 'D';
|
||
break;
|
||
default:
|
||
dare = causale().sezione_clifo() == 'D';
|
||
if (row_type != cgrowtype_totale && row_type != cgrowtype_ritfis)
|
||
dare = !dare;
|
||
break;
|
||
}
|
||
|
||
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 colonne da disabilitare
|
||
switch(tipo)
|
||
{
|
||
case cgrowtype_totale: // Totale documento
|
||
if (causale().corrispettivi())
|
||
{
|
||
last = 2;
|
||
}
|
||
else
|
||
{
|
||
last = 3;
|
||
cg.disable_cell(n, 5);
|
||
cg.disable_cell(n, 6);
|
||
}
|
||
break;
|
||
case cgrowtype_abbattivo: // Abbuoni attivi
|
||
case cgrowtype_diffcambio: // Differenza cambio
|
||
case cgrowtype_IVAdet: // IVA Detraibile
|
||
case cgrowtype_ritfis: // Ritenute Fiscali
|
||
case cgrowtype_contrspesa: // Contropartita delle spese
|
||
case cgrowtype_IVAnondet: // IVA Non detraibile
|
||
case cgrowtype_abbpassivo: // Abbuoni passivi
|
||
case cgrowtype_ritprof: // Ritenute professionali
|
||
case cgrowtype_ritsoc: // Ritenute Sociali
|
||
case cgrowtype_revcharge: // Reverse charge
|
||
case cgrowtype_IVAsplit: // IVA per scissione pagamenti art.17-ter DPR 633/72
|
||
last = 3;
|
||
break;
|
||
case cgrowtype_cliforsc: // 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 cgrowtype_imponibile: // Imponibile o contropartita saldaconto
|
||
case cgrowtype_clisplit: // Cliente per scissione pagamenti art.17-ter DPR 633/72
|
||
last = 7;
|
||
break;
|
||
default:
|
||
last = 0; // Solo contabile
|
||
break;
|
||
}
|
||
|
||
bool needs_update = false;
|
||
|
||
if (last > first)
|
||
{
|
||
for (int i = first; i < last; i++)
|
||
cg.disable_cell(n, i);
|
||
if (first == 0)
|
||
{
|
||
for (short cc = CG_CUP; cc <= CG_DCIG; cc++)
|
||
cg.disable_cell(n, cid2index(cc));
|
||
}
|
||
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,
|
||
const 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.cut(0);
|
||
imp.add_to(row, 0);
|
||
row.add(conto.string(0x3));
|
||
row.add(""); // Codice decrizione
|
||
row.add(desc); // Descrizione aggiuntiva
|
||
if (tipo == cgrowtype_totale) // 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(cgrowtype_totale);
|
||
|
||
if (pos >= 0)
|
||
{
|
||
TBill contro(cg.row(pos), 2, 0x3);
|
||
if (contro.ok())
|
||
row.add(contro.string(0x3));
|
||
}
|
||
else
|
||
row.add(" | | | | ");
|
||
}
|
||
|
||
row.add(tipo, cid2index(CG_ROWTYPE));
|
||
|
||
disable_cgs_cells(n, tipo);
|
||
|
||
return n;
|
||
}
|
||
|
||
|
||
HIDDEN int compare_rows(const TSortable& o1, const TSortable& o2, void* jolly)
|
||
{
|
||
// Totale, Rit.Fisc., Rit.Soc., Rev.Charge, da riga IVA, riga contabile, IVA detr., IVA non detr.
|
||
const char* const sort_order = "TFSVI DN12APRC";
|
||
|
||
const TToken_string& r1 = (const TToken_string&)o1;
|
||
const TToken_string& r2 = (const TToken_string&)o2;
|
||
const TPrimanota_application& a = *(TPrimanota_application*)jolly;
|
||
const char c1 = a.row_type(r1);
|
||
const char c2 = a.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 == nullptr;
|
||
if (!yes)
|
||
{
|
||
if (*dare == '\0' || *dare == ' ' || strcmp(dare,"0") == 0)
|
||
{
|
||
const char* avere = s.get();
|
||
|
||
yes = (avere == nullptr || *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 > cgrowtype_contabile);
|
||
|
||
bool kill = can_remove(r);
|
||
if (kill)
|
||
{
|
||
if (pagamento)
|
||
{
|
||
if (rt == cgrowtype_cliforsc)
|
||
{
|
||
kill = !partite().utilizzata(numreg, i+1);
|
||
if (kill)
|
||
cg_notify(s, i, K_DEL);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// Non eliminare lre righe cliente delle fatture a zero
|
||
if (rt == cgrowtype_totale && r.get_char(2)>='C' && curr_mask().get_real(F_TOTALE) == ZERO)
|
||
kill = false;
|
||
}
|
||
if (kill)
|
||
rows.destroy(i, true);
|
||
}
|
||
}
|
||
if (!pagamento && rowtypes_present) // Il pagamento e' gia' ordinato
|
||
rows.TArray::sort(compare_rows, this); // Pack and sort array
|
||
}
|
||
|
||
|
||
bool TPrimanota_application::ci_sono_importi(const TSheet_field& s) const
|
||
{
|
||
TImporto imp;
|
||
FOR_EACH_SHEET_ROW(s, r, riga) if (riga && !riga->empty_items())
|
||
{
|
||
imp = *riga;
|
||
if (!imp.is_zero())
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
TImporto TPrimanota_application::imposte_split_pay() const
|
||
{
|
||
TImporto imposte;
|
||
TSheet_field& cg = app().cgs();
|
||
|
||
for (int i = 0; i < cg.items(); i++)
|
||
{
|
||
TToken_string& r = cg.row(i);
|
||
const char tipo = app().row_type(r);
|
||
|
||
if (tipo == cgrowtype_IVAsplit)
|
||
{
|
||
TImporto imposta; imposta = r;
|
||
|
||
if (!imposta.is_zero())
|
||
imposte += imposta;
|
||
}
|
||
}
|
||
return imposte;
|
||
}
|
||
|
||
real TPrimanota_application::calcola_saldo() const
|
||
{
|
||
const bool pag = is_pagamento() && !_as400;
|
||
TImporto importo, bilancio, saldaconto;
|
||
|
||
TSheet_field& cgrows = cgs();
|
||
FOR_EACH_SHEET_ROW_BACK(cgrows, i, r)
|
||
{
|
||
importo = *r;
|
||
bilancio += importo;
|
||
if (pag)
|
||
{
|
||
const char tipo = row_type(*r);
|
||
|
||
if (strchr("GK", tipo) != nullptr) // Abbuoni attivi, differenze cambio, spese, ... // (A o P) Abbuoni e (C) Differenze cambio perch<63> c'erano ? non (T) totolae documento perch<63> pagamento
|
||
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 (abs(residuo.valore()) >= 0.001) // if (!residuo.is_zero())
|
||
{
|
||
TPrimanota_application& a = app();
|
||
TMask& m = a.curr_mask();
|
||
TString4 codval;
|
||
if (val)
|
||
codval = m.get(SK_VALUTA);
|
||
TCurrency euro(imptot.valore(), codval);
|
||
|
||
TString msg(255);
|
||
if (is_true_value(codval))
|
||
msg << TR("Il totale documento in valuta") << ' ' << codval;
|
||
else
|
||
msg << TR("Il totale documento inserito");
|
||
msg << TR(" <20> ") << 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 <20> ") << euro.string(true);
|
||
|
||
msg << TR("\nSi desidera correggere il totale documento?");
|
||
ok = a.cgs().yesno_box(msg);
|
||
if (ok)
|
||
{
|
||
m.set(F_TOTALE, cassa.valore());
|
||
a.calcola_saldo();
|
||
}
|
||
}
|
||
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.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 <20> 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 = is_true_value(m.get(SK_VALUTA));
|
||
TImporto saldaconto, saldaconto_val;
|
||
TImporto imposte;
|
||
TSheet_field& cg = a.cgs();
|
||
bool empty = true;
|
||
|
||
for (int i = 0; i < cg.items(); i++)
|
||
{
|
||
TToken_string& r = cg.row(i);
|
||
const char tipo = row_type(r);
|
||
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 <20> completo"), i+1);
|
||
if (m.insert_mode() && c.sospeso())
|
||
return f.error_box(FR("Il conto della riga %d <20> 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 <20> 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)
|
||
{
|
||
if (tipo == cgrowtype_cliforsc || tipo == cgrowtype_totale || a._as400)
|
||
{
|
||
const int currig = i+1;
|
||
const TImporto speso = a.partite().importo_speso(numreg, currig);
|
||
|
||
if (nota && m.get_bool(F_SPLITPAY))
|
||
{
|
||
imposte = a.imposte_split_pay();
|
||
importo -= imposte;
|
||
}
|
||
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 <20> %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
|
||
{
|
||
msg << TR("\nSi desidera correggere l'importo della riga?");
|
||
ok = f.yesno_box(msg);
|
||
if (ok)
|
||
{
|
||
a.set_cgs_imp(i, speso);
|
||
a.calcola_saldo();
|
||
}
|
||
}
|
||
if (!ok)
|
||
return false;
|
||
}
|
||
}
|
||
if (strchr("GKT", tipo) != nullptr) // Abbuoni attivi, differenze cambio, spese, ... // (A o P) Abbuoni e (C) Differenze cambio perch<63> c'erano ?
|
||
{
|
||
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 == cgrowtype_cliforsc || tipo == cgrowtype_totale)
|
||
saldaconto_val += a.partite().importo_speso(numreg, i+1, true, 0x1);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (tipo == cgrowtype_totale && a.is_fattura())
|
||
{
|
||
const TBill c(r, 2, 0x1);
|
||
if (c.tipo() >= 'C') // Riga cliente/fornitore
|
||
empty = false; // Permetto movimenti a ZERO con IVA assente
|
||
}
|
||
}
|
||
}
|
||
|
||
if (empty)
|
||
return f.error_box(TR("Il movimento non ha righe contabili con un importo"));
|
||
|
||
if ((paga || nota) && !a._as400)
|
||
{
|
||
const char sez(a.causale().sezione(2));
|
||
TImporto totdoc(sez, m.get_real(F_TOTALE)); totdoc += imposte;
|
||
bool ok = imptot_error(totdoc, saldaconto, false);
|
||
|
||
if (ok && in_valuta && !saldaconto.is_zero()) // non tolgo le imposte perch<63> penso che lo split payment in valuta non esista
|
||
{
|
||
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, "", cgrowtype_contabile);
|
||
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, cgrowtype_contrspesa);
|
||
cgs().force_update();
|
||
return r;
|
||
}
|
||
|
||
void TPrimanota_application::update_saldo_riga(int r)
|
||
{
|
||
TMask& m = curr_mask();
|
||
|
||
if (m.id2pos(F_SHEETCG) < 0)
|
||
return;
|
||
|
||
TSheet_field& sheet = cgs();
|
||
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 != nullptr)
|
||
{
|
||
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(cgrowtype_contrspesa);
|
||
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 == cgrowtype_spese)
|
||
old_spesa = row;
|
||
else
|
||
old_spesa.valore() = ZERO;
|
||
break;
|
||
case K_TAB:
|
||
if (!selecting)
|
||
{
|
||
TMask& sm = cg.sheet_mask();
|
||
|
||
sm.enable(DLG_DELREC, tipo <= cgrowtype_contabile || tipo == cgrowtype_cliforsc || tipo == cgrowtype_spese);
|
||
sm.enable(CG_RATEO, tipo <= cgrowtype_contabile);
|
||
sm.enable(CG_RISCONTO, tipo <= cgrowtype_contabile);
|
||
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 == cgrowtype_spese)
|
||
{
|
||
if (old_spesa.is_zero())
|
||
old_spesa = row;
|
||
row.add("", 0);
|
||
row.add("", 1);
|
||
}
|
||
else
|
||
{
|
||
if (tipo == cgrowtype_cliforsc)
|
||
a.notify_cgline_deletion(r+1);
|
||
break;
|
||
}
|
||
case K_ENTER:
|
||
if (tipo == cgrowtype_spese)
|
||
{
|
||
TImporto growth; growth = row; growth -= old_spesa;
|
||
|
||
if (!growth.is_zero())
|
||
{
|
||
const int s = type2pos(cgrowtype_contrspesa);
|
||
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 == cgrowtype_cliforsc || tipo == cgrowtype_spese)
|
||
{
|
||
const int k = tipo == cgrowtype_cliforsc ? 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 == cgrowtype_spese)
|
||
{
|
||
const char sezbanca = a.causale().sezione(2);
|
||
if (sezbanca == sez)
|
||
importo.swap_section();
|
||
}
|
||
|
||
a.set_cgs_row(r, importo, conto, desc, tipo);
|
||
|
||
if (tipo == cgrowtype_cliforsc)
|
||
{
|
||
for (int i = 0; i < r; i++)
|
||
{
|
||
const TToken_string& row = cg.row(i);
|
||
|
||
if (row_type(row) != cgrowtype_cliforsc)
|
||
{
|
||
cg.swap_rows(r, i);
|
||
cg.post_select(i);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (!importo.is_zero())
|
||
{
|
||
const int s = type2pos(cgrowtype_contrspesa);
|
||
if (s < 0)
|
||
a.crea_somma_spese(importo);
|
||
else
|
||
a.sub_cgs_imp(s, importo);
|
||
}
|
||
}
|
||
a.calcola_saldo();
|
||
}
|
||
}
|
||
cg.check_row(r);
|
||
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(cgrowtype_totale);
|
||
if (first >= 0)
|
||
{
|
||
TSheet_field& cg = app().cgs();
|
||
const int pos = cg.cid2index(CG_DESCR);
|
||
const TFixed_string old = cg.row(first).get(pos);
|
||
if (old.blank() || f.get().find(old) >= 0)
|
||
{
|
||
cg.row(first).add(f.get(), pos);
|
||
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 <20> 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;
|
||
}
|
||
|
||
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();
|
||
TString4 iva(m.get(102));
|
||
if (iva.blank())
|
||
{
|
||
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) // Siamo in ancora in LIRE!
|
||
{
|
||
imposta = abs(imponibile) * percent / CENTO;
|
||
imposta.ceil();
|
||
if (imponibile.sign() < 0) imposta = -imposta;
|
||
}
|
||
else
|
||
{
|
||
imposta = imponibile * percent / CENTO;
|
||
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();
|
||
const TCodiceIVA iva(f.get());
|
||
|
||
if (m.get_int(IVA_GRUPPO) == 0)
|
||
{
|
||
TBill b; app().IVA2bill(iva, b);
|
||
|
||
char cr[2] = { ((char) b.tipo_cr()) + '0', '\0' };
|
||
m.set(105, *cr > '0' ? cr : "");
|
||
|
||
const char tipo[2] = { b.tipo(), '\0' };
|
||
|
||
m.set(IVA_TIPO, tipo);
|
||
m.set(IVA_GRUPPO, b.gruppo());
|
||
m.set(IVA_CONTO, b.conto());
|
||
const short id = b.tipo() == 'C' ? IVA_CLIENTE : (b.tipo() == 'F' ? IVA_FORNITORE : IVA_SOTTOCONTO);
|
||
m.set(id, b.sottoconto());
|
||
m.set(id+1, b.descrizione());
|
||
|
||
}
|
||
if (app().iva() == iva_acquisti)
|
||
m.set(IVA_INDETRAIBILE, iva.indetraibilita());
|
||
else
|
||
m.reset(IVA_INDETRAIBILE);
|
||
|
||
TMask & main_mask = *app().mask(CGMaskType::_iva);
|
||
const int anno = main_mask.get_int(F_ANNOIVA);
|
||
const TString & codcaus = main_mask.get(F_CODCAUS);
|
||
const TCausale & causale = cached_causale(codcaus,anno);
|
||
|
||
m.set(IVA_REVCHARGE, causale.iva() == iva_acquisti && causale.reverse_charge_pubb() && iva.reverse_charge_attivo() ? "X" : "", 0x03);
|
||
|
||
TMask_field& im = m.field(IVA_IMPONIBILE);
|
||
|
||
im.set_dirty();
|
||
im.on_hit();
|
||
}
|
||
else
|
||
{
|
||
if (key == K_ENTER)
|
||
{
|
||
if (f.get().empty() && f.mask().get(IVA_IMPONIBILE).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 / CENTO;
|
||
imposta.ceil();
|
||
if (imponibile.sign() < 0) imposta = -imposta;
|
||
}
|
||
else
|
||
{
|
||
imposta = imponibile * percent / CENTO;
|
||
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_EACH_ARRAY_ROW(rows, r, row) if (!row->empty_items())
|
||
{
|
||
imponibili += row->get_real(cid2index(IVA_IMPONIBILE));
|
||
if (_causale->reg().tipo_registro() != acquisto || !row->get_bool(cid2index(IVA_REVCHARGE)))
|
||
imposte += row->get(cid2index(IVA_IMPOSTA));
|
||
}
|
||
|
||
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);
|
||
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.is_zero()) continue;
|
||
const real imposta(r.get(3));
|
||
if (!imposta.is_zero()) continue;
|
||
rows.destroy(i, false);
|
||
}
|
||
rows.pack(); // Pack array
|
||
}
|
||
|
||
int TPrimanota_application::get_importi_iva(TToken_string& row, real& imp_det, real& iva_det,
|
||
real& imp_ind, real& iva_ind)
|
||
{
|
||
const real imptot = row.get_real(cid2index(IVA_IMPONIBILE)); // Importo scritto nella riga iva
|
||
const TString4 zanicchi = row.get(cid2index(IVA_CODIVA)); // Codice IVA
|
||
const TString4 codind = row.get(cid2index(IVA_INDETRAIBILE)); // Codice indetraibilit<69>
|
||
const real ivatot = row.get_real(cid2index(IVA_IMPOSTA)); // Imposta scritta nella riga iva
|
||
|
||
int annodoc = app()._msk[2]->get_date(F_DATADOC).year();
|
||
if (annodoc <= 0)
|
||
{
|
||
annodoc = app()._msk[2]->get_date(F_DATAREG).year();
|
||
if (annodoc <= 0)
|
||
annodoc = TDate(TODAY).year();
|
||
}
|
||
|
||
const TCausale& caus = app().causale();
|
||
const TMovimentoPN& mov = (const TMovimentoPN&)*app().get_relation();
|
||
|
||
return mov.analizza_riga_IVA(imptot, ivatot, caus, annodoc, zanicchi, codind,
|
||
imp_det, iva_det, imp_ind, iva_ind);
|
||
}
|
||
|
||
void TPrimanota_application::add2cg_row(TSheet_field& s, TToken_string & row, TString_array & saved_descr, const bool add)
|
||
{
|
||
TPrimanota_application& a = app();
|
||
const TCausale& cau = a.causale();
|
||
const bool acquisto = (a.iva() == iva_acquisti);
|
||
const int last = acquisto ? 3 : 2;
|
||
static TString8 __tipi;
|
||
|
||
if (__tipi.blank())
|
||
__tipi << (char) cgrowtype_IVAnondet << (char) cgrowtype_IVAdet << (char) cgrowtype_revcharge;
|
||
|
||
|
||
real imp_det, iva_det, imp_ind, iva_ind;
|
||
const bool revcharge = row.get_bool(cid2index(IVA_REVCHARGE));
|
||
get_importi_iva(row, imp_det, iva_det, imp_ind, iva_ind);
|
||
|
||
for (int d = 0; d < last; d++)
|
||
{
|
||
const char tipod = __tipi[d];
|
||
|
||
if (d < 2)
|
||
{
|
||
const TBill conto(row, cid2index(IVA_TIPO), 0x1);
|
||
const int pos = bill2pos(conto, cgrowtype_imponibile); // Riga in cui andra' l'imponibile
|
||
const TImporto imp = a.real2imp(d > 0 ? imp_det : imp_ind, tipod); // Imponibile
|
||
|
||
if (pos >= 0) // Se il conto esisteva anche prima ...
|
||
{
|
||
TImporto i(a.get_cgs_imp(pos));
|
||
|
||
if (add)
|
||
i += imp;
|
||
else
|
||
{
|
||
i -= imp;
|
||
saved_descr.add(a.cgs().row(pos).get(cid2index(CG_DESCR)), d); // Memorizza vecchia descrizionei += iva;
|
||
}
|
||
i.normalize();
|
||
if (i.is_zero())
|
||
a.reset_cgs_row(pos);
|
||
else
|
||
a.set_cgs_imp(pos, i);
|
||
}
|
||
else
|
||
{
|
||
if (add && conto.ok() && !imp.is_zero()) // Se c'e' imponibile ...
|
||
a.set_cgs_row(-1, imp, conto, (saved_descr.objptr(d) == nullptr || saved_descr.row(d).blank()) ? cau.desc_agg(2) : saved_descr.row(d), cgrowtype_imponibile);
|
||
}
|
||
}
|
||
// Aggiorna conto IVA sulla riga contabile
|
||
const int posiva = type2pos(tipod);
|
||
real imposta(d > 0 ? iva_det : iva_ind);
|
||
|
||
if (d == 2)
|
||
{
|
||
TBill billind; cau.bill(RIGA_IVA_NON_DETRAIBILE, billind);
|
||
const bool iva_ind_al_costo = !billind.ok();
|
||
|
||
imposta = revcharge ? row.get_real(cid2index(IVA_IMPOSTA)) : ZERO;
|
||
}
|
||
|
||
TImporto iva = a.real2imp(imposta, tipod); // Imponibile
|
||
TImporto i(a.get_cgs_imp(posiva));
|
||
|
||
if (posiva >= 0) // Se conto IVA esisteva anche prima ...
|
||
{
|
||
if (add)
|
||
i += iva;
|
||
else
|
||
i -= iva;
|
||
i.normalize();
|
||
if (i.is_zero())
|
||
a.reset_cgs_row(posiva);
|
||
else
|
||
a.set_cgs_imp(posiva, i);
|
||
}
|
||
else
|
||
if (add & !iva.is_zero()) // Se c'e' imposta ...
|
||
{ // ... crea nuova riga per l'IVA
|
||
TBill contoiva;
|
||
int ri = 0;
|
||
TMask & main_mask = s.mask();
|
||
|
||
if (d > 0)
|
||
{
|
||
if (d == 2 && revcharge)
|
||
cau.bill(ri = RIGA_REVERSE_CHARGE, contoiva);
|
||
else
|
||
{
|
||
if (main_mask.active(F_LIQDIFF) && main_mask.get_bool(F_LIQDIFF))
|
||
cau.bill(ri = RIGA_IVA_DIFFERITA, contoiva);
|
||
else
|
||
if (main_mask.active(F_IVAXCASSA) && main_mask.get_bool(F_IVAXCASSA))
|
||
cau.bill(ri = RIGA_IVA_PER_CASSA, contoiva);
|
||
if (!contoiva.ok())
|
||
cau.bill(ri = RIGA_IVA_DETRAIBILE, contoiva);
|
||
}
|
||
}
|
||
else
|
||
cau.bill(ri = RIGA_IVA_NON_DETRAIBILE, contoiva);
|
||
a.set_cgs_row(-1, iva, contoiva, cau.desc_agg(ri), tipod);
|
||
}
|
||
} // for (int d = 0; d < 2; d++)
|
||
}
|
||
|
||
bool TPrimanota_application::iva_notify(TSheet_field& s, int r, KEY k)
|
||
{
|
||
static bool selecting = false;
|
||
TPrimanota_application& a = app();
|
||
|
||
if (!a._as400)
|
||
{
|
||
TToken_string& row = s.row(r);
|
||
const TCausale& cau = a.causale();
|
||
|
||
if (k == K_TAB)
|
||
{
|
||
if (!selecting && row.empty_items())
|
||
{
|
||
selecting = true;
|
||
s.select(r, 1); // Vado alla prima colonna delle righe vuote
|
||
selecting = false;
|
||
|
||
}
|
||
return true;
|
||
}
|
||
|
||
if (k == K_DEL) // Cancellazione di una riga
|
||
{
|
||
row.add("0", cid2index(IVA_IMPONIBILE)); // Azzera imponibile
|
||
row.add("0", cid2index(IVA_IMPOSTA)); // Azzera imposta
|
||
k = K_ENTER; // Elegante o Sporco trucco (dipende dai gusti!)
|
||
}
|
||
if (k == K_ENTER)
|
||
{
|
||
TToken_string& original_row = s.original_row(r);
|
||
TToken_string& row = s.row(r);
|
||
TString_array saved_descr;
|
||
|
||
a.sub2cg_row(s, original_row, saved_descr);
|
||
a.add2cg_row(s, row, saved_descr);
|
||
|
||
const bool acquisto_revcharge = (a.iva() == iva_acquisti) && (cau.reverse_charge_pubb());
|
||
|
||
if (acquisto_revcharge)
|
||
{
|
||
TImporto tot_revcharge;
|
||
const int posiva = type2pos(cgrowtype_revcharge);
|
||
TEdit_field & revcharge = a.curr_mask().efield(F_REVCHARGE);
|
||
|
||
if (posiva >= 0)
|
||
tot_revcharge = a.get_cgs_imp(posiva);
|
||
revcharge.set(tot_revcharge.valore().string());
|
||
revcharge.on_hit();
|
||
}
|
||
|
||
// Controllo split-payment (dalla versione 12)
|
||
TMask& m = a.curr_mask();
|
||
const TString4 tipocf(a.clifo());
|
||
|
||
if (m.get_int(F_ANNOIVA) >= 2015 && (tipocf == "C") && a.get_version() >= 12)
|
||
{
|
||
const int r_norm = type2pos(cgrowtype_IVAdet);
|
||
const bool split_needed = r_norm >= 0 && a.is_split_payment();
|
||
|
||
if (split_needed)
|
||
{
|
||
TImporto imp_split = a.get_cgs_imp(r_norm);
|
||
const int r_split1 = type2pos(cgrowtype_clisplit);
|
||
|
||
if (r_split1 < 0)
|
||
{
|
||
const int r_tot = max(0, type2pos(cgrowtype_totale));
|
||
TToken_string row_tot = a.cgs().row(r_tot);
|
||
TBill cliente_split(row_tot, 2, 0x1); // Imposta anche tipo = Cliente
|
||
const char* desc = TR("IVA art.17-ter D.P.R. 633/1972");
|
||
|
||
a.set_cgs_row(-1, imp_split, cliente_split, desc, cgrowtype_clisplit);
|
||
}
|
||
else
|
||
a.set_cgs_imp(r_split1, imp_split);
|
||
|
||
const int r_split2 = type2pos(cgrowtype_IVAsplit);
|
||
|
||
imp_split.swap_section();
|
||
if (r_split2 < 0)
|
||
{
|
||
TToken_string row_norm = a.cgs().row(r_norm);
|
||
TBill iva_split(row_norm, 3);
|
||
const char* desc = TR("IVA art.17-ter D.P.R. 633/1972");
|
||
|
||
a.set_cgs_row(-1, imp_split, iva_split, desc, cgrowtype_IVAsplit);
|
||
}
|
||
else
|
||
a.set_cgs_imp(r_split2, imp_split);
|
||
}
|
||
else
|
||
{
|
||
const int r_split2 = type2pos(cgrowtype_IVAsplit);
|
||
|
||
if (r_split2 >= 0)
|
||
a.reset_cgs_row(r_split2);
|
||
|
||
const int r_split1 = type2pos(cgrowtype_clisplit);
|
||
|
||
if (r_split1 >= 0)
|
||
a.reset_cgs_row(r_split1);
|
||
}
|
||
}
|
||
|
||
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 (m.insert_mode() && a.is_fattura())
|
||
{
|
||
TPagamento& pag = a.pagamento();
|
||
const TValuta cambio(m, SK_VALUTA, SK_DATACAMBIO, SK_CAMBIO);
|
||
const bool inv = cambio.in_valuta();
|
||
real imposta, imponibile;
|
||
|
||
if (inv)
|
||
{
|
||
const real il = m.get(F_IMPOSTE);
|
||
|
||
imposta = cambio.eur2val(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));
|
||
|
||
pimposta.round(pag.round(inv));
|
||
|
||
real pimponibile(pag.imponibile(inv));
|
||
|
||
pimponibile.round(pag.round(inv));
|
||
if ((pimposta != imposta || pimponibile != imponibile) && (!a._f1_ini && (a._pro_mask == nullptr || !a._pro_mask->should_bring_back())))
|
||
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) <EFBFBD> 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 <20> obbligatorio"), i+1);
|
||
|
||
TBill c(row, 5, 0x1);
|
||
|
||
if (!c.ok() || !c.find())
|
||
return error_box(FR("Il conto della riga iva %d <20> errato o incompleto"), i+1);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
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_ENTER)
|
||
{
|
||
TMask& m = f.mask();
|
||
|
||
if (m.get(CG_ROWTYPE)[0] == cgrowtype_totale && !app().causale().corrispettivi())
|
||
{
|
||
const TString4 tipo = app().clifo(); // Tipo conto richiesto dal movimento
|
||
TString4 cf = m.get(f.dlg()-2);
|
||
|
||
if (cf[0] < ' ') 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(PCN_TIPOSPRIC);
|
||
|
||
if (app().iva() == iva_vendite)
|
||
{
|
||
if (spric == 2 || spric == 3)
|
||
{
|
||
const TCausale& caus = app().causale();
|
||
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
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
bool TPrimanota_application::cg_sottoconto_handler(TMask_field& f, KEY k)
|
||
{
|
||
return suspended_handler(f, k);
|
||
}
|
||
|
||
bool TPrimanota_application::sheet_clifo_handler(TMask_field& f, KEY k)
|
||
{
|
||
if (suspended_handler(f, k) && (k == K_TAB || k == K_ENTER))
|
||
{
|
||
const long codice = f.get_long();
|
||
|
||
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;
|
||
}
|
||
|
||
void TPrimanota_application::link_mastrino(const TBill& bill) const
|
||
{
|
||
if (bill.ok())
|
||
{
|
||
TPrimanota_application& a = app();
|
||
const TMask& cm = a.curr_mask();
|
||
int anno = cm.get_int(F_ANNOES);
|
||
|
||
if (anno <= 0)
|
||
{
|
||
TDate date = cm.get(F_DATACOMP);
|
||
|
||
if (!date.ok())
|
||
{
|
||
date = cm.get_date(F_DATAREG);
|
||
if (!date.ok())
|
||
date = TDate(TODAY);
|
||
}
|
||
anno = a._esercizi.date2esc(date);
|
||
}
|
||
|
||
TFilename ininame; ininame.tempdir(); ininame.add("mastrino.ini");
|
||
if (anno > 0)
|
||
{
|
||
TConfig ini(ininame, "Transaction");
|
||
|
||
ini.set("Action", "Modify");
|
||
ini.set_paragraph("24");
|
||
ini.set(RMV_ANNOES, anno);
|
||
const char tipo[2] = { bill.tipo(), '\0' };
|
||
ini.set(RMV_TIPOC, tipo); // Non esiste la TConfig::set(const char* name, char value);
|
||
ini.set(RMV_GRUPPO, bill.gruppo());
|
||
ini.set(RMV_CONTO, bill.conto());
|
||
ini.set(RMV_SOTTOCONTO, bill.sottoconto());
|
||
}
|
||
if (ininame.exist())
|
||
{
|
||
TString cmd;
|
||
|
||
cmd << "cg3 -5 -i" << ininame;
|
||
TExternal_app app(cmd);
|
||
app.run();
|
||
ininame.fremove();
|
||
}
|
||
}
|
||
}
|
||
|
||
bool TPrimanota_application::mastrino_handler(TMask_field& f, KEY k)
|
||
{
|
||
if (k == K_SPACE)
|
||
{
|
||
const TMask& m = f.mask();
|
||
TBill bill; bill.get(m, F_GRUPPO, F_CONTO, F_SOTTOCONTO);
|
||
|
||
app().link_mastrino(bill);
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool TPrimanota_application::sheet_mastrino_handler(TMask_field& f, KEY k)
|
||
{
|
||
if (k == K_SPACE)
|
||
{
|
||
const TMask& m = f.mask();
|
||
const char tipo = m.get(CG_TIPO)[0];
|
||
const short id_sotto = CG_SOTTOCONTO + (tipo <= ' ' ? 0 : (tipo == 'C' ? 100 : 200));
|
||
TBill bill; bill.get(m, CG_GRUPPO, CG_CONTO, id_sotto, CG_TIPO);
|
||
|
||
app().link_mastrino(bill);
|
||
}
|
||
return true;
|
||
}
|
||
|
||
class TRR_mask : public TAutomask
|
||
{
|
||
bool _rateo;
|
||
|
||
protected:
|
||
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
|
||
bool test_date(TOperable_field& d, int signum);
|
||
void notify(TSheet_field& s, int row, KEY k) const;
|
||
|
||
public:
|
||
bool split_row(TSheet_field& s);
|
||
TRR_mask(bool is_rateo);
|
||
};
|
||
|
||
void TRR_mask::notify(TSheet_field& s, int row, KEY k) const
|
||
{
|
||
if (s.dlg() == F_SHEETIVA)
|
||
app().iva_notify(s, row, k);
|
||
else
|
||
app().cg_notify(s, row, k);
|
||
}
|
||
|
||
bool TRR_mask::test_date(TOperable_field& d, int signum)
|
||
{
|
||
const TDate date = d.get();
|
||
|
||
if (!date.ok())
|
||
return error_box(TR("Data non valida"));
|
||
|
||
const int codes = app().curr_mask().get_int(F_ANNOES);
|
||
TEsercizi_contabili esc;
|
||
TDate inies, fines;
|
||
|
||
if (!esc.code2range(codes, inies, fines))
|
||
return error_box(TR("E' necessario specificare una esercizio valido"));
|
||
if (signum < 0 && date >= inies)
|
||
return error_box(FR("La data deve precedere il %s"), inies.stringa());
|
||
if (signum == 0 && (date < inies || date > fines))
|
||
return error_box(FR("La data deve appartenere all'esercizio %d"), codes);
|
||
if (signum > 0 && date <= fines)
|
||
return error_box(FR("La data deve seguire il %s"), fines.stringa());
|
||
|
||
return true;
|
||
}
|
||
|
||
bool TRR_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
||
{
|
||
bool ok = true;
|
||
|
||
switch (o.dlg())
|
||
{
|
||
case 101:
|
||
if (e == fe_modify || e == fe_close)
|
||
ok = test_date(o, _rateo ? 0 : -1);
|
||
break;
|
||
case 102:
|
||
if (e == fe_modify || e == fe_close)
|
||
ok = test_date(o, _rateo ? +1 : 0);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
bool TRR_mask::split_row(TSheet_field& s)
|
||
{
|
||
const int sel = s.selected();
|
||
CHECKD(sel >= 0 && sel < s.items(), "Bad selection:", sel);
|
||
TMask& main_mask = s.mask();
|
||
TMask& row_mask = s.sheet_mask();
|
||
|
||
TEsercizi_contabili esc;
|
||
const int codes = main_mask.get_int(F_ANNOES);
|
||
TDate inies, fines;
|
||
|
||
if (!esc.code2range(codes, inies, fines))
|
||
return error_box(TR("Specificare una data di competenza per il movimento"));
|
||
|
||
const TDate dataini = get_date(101), datafin = get_date(102);
|
||
const real tot_range = datafin - dataini + 1;
|
||
const real in_range = (_rateo ? (fines-dataini) : (datafin-inies)) + 1;
|
||
const real out_range = tot_range - in_range;
|
||
const bool iva_sheet = s.dlg() == F_SHEETIVA;
|
||
const short col1 = iva_sheet ? IVA_IMPONIBILE : CG_DARE;
|
||
const short col2 = iva_sheet ? IVA_IMPOSTA : CG_AVERE;
|
||
const short col3 = iva_sheet ? IVA_GRUPPO : CG_GRUPPO;
|
||
const real old_imp1 = row_mask.get(col1);
|
||
const real old_imp2 = row_mask.get(col2);
|
||
real new_imp1[2], new_imp2[2];
|
||
|
||
new_imp1[0] = real(old_imp1 * in_range / tot_range).round(2);
|
||
new_imp2[0] = real(old_imp2 * in_range / tot_range).round(2);
|
||
new_imp1[1] = old_imp1 - new_imp1[0];
|
||
new_imp2[1] = old_imp2 - new_imp2[0];
|
||
|
||
for (int i = 0; i < 2; i++)
|
||
{
|
||
TToken_string& new_row = s.row(-1);
|
||
const int new_sel = s.rows_array().find(new_row);
|
||
|
||
notify(s, new_sel, K_SPACE); // Notifica l'intenzione di modificare i valori
|
||
|
||
row_mask.set(col1, new_imp1[i]);
|
||
row_mask.set(col2, new_imp2[i]);
|
||
|
||
if (i == 1)
|
||
{
|
||
// Utilizza i conti scritti nei paramentri ditta
|
||
TConfig ini(CONFIG_DITTA, "cg");
|
||
|
||
row_mask.reset(col3-1); // Forza conto normale
|
||
if (_rateo)
|
||
{
|
||
row_mask.set(col3+0, ini.get("RateiG"));
|
||
row_mask.set(col3+1, ini.get("RateiC"));
|
||
row_mask.set(col3+2, ini.get("RateiS"), 0x2);
|
||
}
|
||
else
|
||
{
|
||
row_mask.set(col3+0, ini.get("RiscontiG"));
|
||
row_mask.set(col3+1, ini.get("RiscontiC"));
|
||
row_mask.set(col3+2, ini.get("RiscontiS"), 0x2);
|
||
}
|
||
}
|
||
|
||
// Trasferisce tutta la maschera nella rispettiva riga dello sheet
|
||
FOR_EACH_MASK_FIELD(row_mask, j, f) if (f->shown() && f->dlg() > DLG_USER)
|
||
new_row.add(f->get(), cid2index(f->dlg()));
|
||
|
||
notify(s, new_sel, K_ENTER); // Notifica l'avvenuta modifica dei valori
|
||
}
|
||
notify(s, sel, K_SPACE); // Riposiziona selezione sulla riga corrente da cancellare
|
||
return true;
|
||
}
|
||
|
||
TRR_mask::TRR_mask(bool is_rateo)
|
||
: TAutomask(is_rateo ? TR("Rateo") : TR("Risconto"), 1, 24, 4), _rateo(is_rateo)
|
||
{
|
||
add_button_tool(DLG_OK, "", TOOL_OK);
|
||
add_button_tool(DLG_CANCEL, "", TOOL_CANCEL);
|
||
add_date(101, 0, PR("Dal "), 1, 1).check_type(CHECK_REQUIRED);
|
||
add_date(102, 0, PR("Al "), 1, 2).check_type(CHECK_REQUIRED);
|
||
set_handlers();
|
||
}
|
||
|
||
bool TPrimanota_application::sheet_rateo_handler(TMask_field& f, KEY k)
|
||
{
|
||
if (k == K_SPACE)
|
||
{
|
||
TMask& row_mask = f.mask();
|
||
|
||
if (row_mask.is_running() && row_mask.check_fields())
|
||
{
|
||
TRR_mask rateo_mask(true);
|
||
|
||
if (rateo_mask.run() == K_ENTER)
|
||
{
|
||
TSheet_field& s = *row_mask.get_sheet();
|
||
rateo_mask.split_row(s);
|
||
row_mask.send_key(K_SPACE, DLG_DELREC);
|
||
}
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool TPrimanota_application::sheet_risconto_handler(TMask_field& f, KEY k)
|
||
{
|
||
if (k == K_SPACE)
|
||
{
|
||
TMask& row_mask = f.mask();
|
||
|
||
if (row_mask.is_running() && row_mask.check_fields())
|
||
{
|
||
TRR_mask risconto_mask(false);
|
||
if (risconto_mask.run() == K_ENTER)
|
||
{
|
||
risconto_mask.split_row(*row_mask.get_sheet());
|
||
row_mask.send_key(K_SPACE, DLG_DELREC);
|
||
}
|
||
}
|
||
}
|
||
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)
|
||
{
|
||
bool ok = true;
|
||
TPrimanota_application& a = app();
|
||
|
||
if (f.final_check(key) && a.autodeleting() != 0x3)
|
||
{
|
||
TMask& m = f.mask();
|
||
const TRectype& mov = cache().get(LF_MOV, f.get());
|
||
|
||
a._skip_giornale_check = false;
|
||
a._skip_bollato_check = false;
|
||
if (!mov.empty())
|
||
{
|
||
if (mov.get_bool(MOV_STAMPATO))
|
||
ok = f.yesno_box(TR("Il movimento <20> gi<67> stato stampato sul libro giornale:\n"
|
||
"si desidera continuare ugualmente?"));
|
||
a._skip_giornale_check = true;
|
||
if (ok && mov.get_bool(MOV_REGST))
|
||
ok = f.yesno_box(TR("Il movimento <20> gi<67> stato stampato sul bollato:\n"
|
||
"si desidera continuare ugualmente?"));
|
||
a._skip_bollato_check = true;
|
||
if (ok && mov.get_bool(MOV_INVIATO))
|
||
ok = f.yesno_box(TR("Il movimento <20> stato inviato ad un'altra contabilit<69>:\n"
|
||
"si desidera continuare ugualmente?"));
|
||
}
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
|
||
// Handler of the F_CODCAUS field on the query mask
|
||
// Certified 99%
|
||
bool TPrimanota_application::caus_query_handler(TMask_field& f, KEY key)
|
||
{
|
||
if (key == K_TAB || key == K_ENTER)
|
||
{
|
||
const TMask& m = f.mask();
|
||
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 && m.is_running())
|
||
return f.error_box(TR("Causale non presente in archivio"));
|
||
|
||
TEdit_field& numreg = m.efield(F_NUMREG);
|
||
TString16 filter;
|
||
|
||
if (cau.full())
|
||
filter << MOV_CODCAUS << "==\"" << cau << '"';
|
||
numreg.browse()->set_filter(filter);
|
||
numreg.browse()->cursor()->setfilter(filter, true);
|
||
|
||
return suspended_handler(f, key); // Controlla sospensione
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
void TPrimanota_application::check_fppro_fields(TMask& m)
|
||
{
|
||
const bool after_data = m.get_date(F_DATAREG) >= get_data_start_fatt();
|
||
|
||
if (!check_causale(m.get(F_CODCAUS)) || !app().has_module(FPAUT) || !after_data)
|
||
{
|
||
if(m.find_by_id(DLG_LINK) != nullptr)
|
||
m.disable(DLG_LINK);
|
||
if (m.find_by_id(F_COLFPPRO) != nullptr)
|
||
m.hide(F_COLFPPRO);
|
||
}
|
||
else
|
||
{
|
||
if (m.find_by_id(DLG_LINK) != nullptr)
|
||
m.enable(DLG_LINK);
|
||
if (m.find_by_id(F_COLFPPRO) != nullptr)
|
||
m.show(F_COLFPPRO);
|
||
}
|
||
}
|
||
|
||
// 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.running_check(key))
|
||
{
|
||
if (suspended_handler(f, key))
|
||
{
|
||
TMask& m = f.mask();
|
||
const int ann = m.get_int(F_ANNOIVA);
|
||
const TString& cau = f.get();
|
||
const TCausale c(cau, ann);
|
||
|
||
if (c.ok())
|
||
{
|
||
TPrimanota_application& a = app();
|
||
const TCausale& k = a.causale();
|
||
TString8 codice = c.codice();
|
||
const TipoIVA t = k.iva();
|
||
TMask * new_mask = &m;
|
||
|
||
if (codice != k.codice())
|
||
{
|
||
const TString& msg = c.compatible(k);
|
||
|
||
if (msg.not_empty()) // La causale non <20> compatibile
|
||
{
|
||
if (!m.insert_mode() || a._sal_dirty || !a.force_mask_swap(k, c)) // Cambio la maschera al volo
|
||
return error_box(msg);
|
||
new_mask = a._msk[c.iva() == nessuna_iva ? 1 : 2];
|
||
}
|
||
a.read_caus(cau, ann);
|
||
if (new_mask != nullptr) // Non tentare di aggiornare sheet al momento inesistente essendo la causale incompatibile
|
||
{
|
||
TString4 provv; provv << c.provvisorio();
|
||
|
||
a.cgs().force_update();
|
||
new_mask->set(F_PROVVISORIO, provv);
|
||
if (c.iva() != nessuna_iva)
|
||
{
|
||
new_mask->set(F_SOLAIVA, c.soloiva() ? "X" : " ");
|
||
new_mask->show(F_REVCHARGE, c.iva() == iva_acquisti && c.reverse_charge_pubb());
|
||
new_mask->show(F_MOVCOLL, (c.iva() == iva_acquisti && c.reverse_charge_pubb()) ||
|
||
(c.iva() == iva_vendite && c.causale_reg_iva()));
|
||
a.activate_split_payment(m);
|
||
// Se la causale ha come tipo documento una bolla doganale, se si abilito i campi per collegare il fornitore
|
||
new_mask->enable(F_BOLLACODCLI, c.tipo_doc() == "BD");
|
||
new_mask->enable(F_BOLLARAGCLI, c.tipo_doc() == "BD");
|
||
|
||
const long protocol = app().causale().reg().protocol() + 1;
|
||
|
||
new_mask->set(F_PROTIVA, protocol);
|
||
new_mask->set(F_RITFATT, app().causale().fattura_in_ritardo() ? "X" : " ");
|
||
}
|
||
check_fppro_fields(*new_mask);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
|
||
// Handler of the F_DATAREG field
|
||
// Certified 70%
|
||
bool TPrimanota_application::datareg_handler(TMask_field& f, KEY key)
|
||
{
|
||
bool ok = true;
|
||
|
||
// if (key == K_TAB && f.focusdirty() || key == K_ENTER)
|
||
if (f.to_check(key))
|
||
{
|
||
const TDate oggi(TODAY);
|
||
TDate dr(f.get()); // Data dell'operazione
|
||
|
||
if (dr > oggi)
|
||
{
|
||
#ifdef DBG
|
||
if (!yesno_box(TR("La data dell'operazione <20> superiore quella di sistema:\nContinuare ugualmente?")))
|
||
return false;
|
||
#else
|
||
return f.error_box(TR("La data dell'operazione <20> superiore quella di sistema"));
|
||
#endif
|
||
}
|
||
|
||
TMask& m = f.mask();
|
||
TPrimanota_application& a = app();
|
||
|
||
if (dr == oggi && m.query_mode() && !m.field(F_NUMREG).empty())
|
||
dr = TDate(cache().get(LF_MOV, m.get_long(F_NUMREG), MOV_DATAREG));
|
||
if (!m.query_mode() && a.iva() != nessuna_iva)
|
||
m.enable(F_IVAXCASSA, gestione_IVAxCassa(dr));
|
||
|
||
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 ag = a._esercizi[ae].inizio().year(); // Anno libro giornale
|
||
|
||
if (m.query_mode() || gio.year() != ag)
|
||
if (!gio.read(ag))
|
||
return f.error_box(FR("Non esiste il libro giornale del %d"), ag);
|
||
|
||
if (key == K_ENTER || f.focusdirty())
|
||
{
|
||
if (key != K_ENTER && !a._skip_giornale_check)
|
||
{
|
||
if (dr < gio.last_print())
|
||
return error_box(FR("La data dell'operazione <20> antecedente al %s,\n"
|
||
"ultima stampa del libro giornale del %d"),
|
||
gio.last_print().string(), ag);
|
||
if (key == K_TAB && dr < gio.last_reg())
|
||
warning_box(FR("La data dell'operazione <20> antecedente al %s,\n"
|
||
"ultima registrazione sul libro giornale del %d"),
|
||
gio.last_reg().string(), ag);
|
||
}
|
||
if (a.iva() != nessuna_iva)
|
||
{
|
||
const int ar = dr.year(); // Anno solare registri
|
||
const TCausale & caus = cached_causale(m.get(F_CODCAUS), ar);
|
||
TRegistro& reg = (TRegistro &) caus.reg();
|
||
const TString4 codreg = reg.name();
|
||
|
||
if (codreg.full())
|
||
{
|
||
if (!a._skip_bollato_check)
|
||
{
|
||
if (a._rel->controlla_liquidazione(dr, reg) == true)
|
||
f.warning_box(FR("La liquidazione IVA relativa al mese di %s <20> gi<67> stata calcolata"), itom(dr.month()));
|
||
if (f.dirty() && dr < reg.last_reg())
|
||
f.warning_box(FR("La data dell'operazione <20> antecedente al %s,\n"
|
||
"ultima registrazione sul registro '%s' del %d"),
|
||
reg.last_reg().string(), (const char*)codreg, ar);
|
||
if (dr < reg.last_print())
|
||
ok = yesno_box(FR("La data dell'operazione <20> antecedente al %s,\n"
|
||
"ultima stampa del registro '%s' del %d\nSi desidera continuare ugualmente?"),
|
||
reg.last_print().string(), (const char*)codreg, ar);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
check_fppro_fields(f.mask());
|
||
}
|
||
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
|
||
TDate datacomp = f.get_date();
|
||
|
||
if (!datacomp.ok())
|
||
{
|
||
datacomp = dr;
|
||
if (key == K_ENTER)
|
||
f.set(datacomp);
|
||
}
|
||
|
||
TEsercizi_contabili& esc = app()._esercizi;
|
||
const int ae = esc.date2esc(datacomp); // Esercizio corrispondente
|
||
TString dmsg(TR("La data del 74/ter"));
|
||
|
||
if (f.dlg() == F_DATACOMP)
|
||
{
|
||
m.set(F_ANNOES, ae, true); // Aggiorna anno esercizio in entrambe le pagine
|
||
dmsg = TR("La data di competenza");
|
||
|
||
if (datacomp > 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(TR("La data di competenza non puo' superare la data di registrazione"));
|
||
}
|
||
}
|
||
|
||
if (ae > 0)
|
||
{
|
||
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"), (const char *) dmsg, ar);
|
||
if (pr > 0) e << TR(" o all'esercizio ") << pr;
|
||
return f.error_box(e);
|
||
}
|
||
|
||
const TDate chiusura = app()._esercizi[ae].chiusura();
|
||
|
||
if (chiusura.ok() && datacomp < chiusura)
|
||
f.error_box(FR("%s <20> antecedente al %s,\ndata di chiusura dell'esercizio %d"),
|
||
(const char *) dmsg, chiusura.stringa(), ae); // Errore non bloccante
|
||
else
|
||
if (chiusura.ok() && datacomp == chiusura)
|
||
f.error_box(FR("%s <20> uguale al %s,\ndata di chiusura dell'esercizio %d"),
|
||
(const char *) dmsg, chiusura.stringa(), ae); // Errore non bloccante
|
||
}
|
||
else
|
||
if (m.is_running())
|
||
return f.error_box(FR("%s non appartiene a nessun esercizio"), (const char *) dmsg);
|
||
}
|
||
return true;
|
||
}
|
||
|
||
// Handler of the F_DATACOMP field on the modify mask
|
||
// Certified 90%
|
||
bool TPrimanota_application::datacompcr_handler(TMask_field& f, KEY key)
|
||
{
|
||
TMask& m = f.mask();
|
||
|
||
if (key == K_ENTER)
|
||
{
|
||
const TDate dr(m.get(F_DATAREG)); // Data operazione
|
||
TDate datacompcr = f.get_date();
|
||
|
||
if (!datacompcr.ok())
|
||
{
|
||
datacompcr = dr;
|
||
f.set(datacompcr);
|
||
}
|
||
|
||
if (datacompcr > dr)
|
||
return f.message_box(TR("La data di competenze costi/ricavi maggiore di %s"), dr.stringa());
|
||
}
|
||
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))
|
||
{
|
||
const TDate dr = f.mask().get_date(F_DATAREG); // Data operazione
|
||
const TDate d74 = f.get_date(); // Data 74/ter
|
||
|
||
if (d74 <= dr)
|
||
{
|
||
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() != nessuna_iva)
|
||
{
|
||
TMask& m = f.mask();
|
||
const int annodoc = m.get_date(F_DATADOC).year();
|
||
const long fornitore = m.get_long(F_CODCLIFOR);
|
||
|
||
if (annodoc > 0 && fornitore > 0)
|
||
{
|
||
// SELECT NUMREG,DATAREG,DATADOC,NUMDOC FROM MOV
|
||
// WHERE TIPO='F' AND CODCF=F_FORNITORE AND REG<>'' AND
|
||
// NUMDOC=F_NUMDOC AND DATAREG>=F_DATADOC AND NUMREG<>F_NUMREG
|
||
|
||
TString filter;
|
||
|
||
filter << '(' << MOV_NUMDOC << "=\"" << f.get() << "\")&&(" << MOV_REG << "!=\"\")";
|
||
if (m.edit_mode())
|
||
filter << "&&(" << MOV_NUMREG << "!=\"" << m.get(F_NUMREG) << "\")";
|
||
|
||
TRelation rel(LF_MOV);
|
||
TRectype& rec = rel.curr();
|
||
TRectype recfrom(rec);
|
||
|
||
recfrom.put(MOV_TIPO, app().iva() == iva_acquisti ? "F" : "C");
|
||
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 <20> gi<67> 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::ndocext_handler(TMask_field& f, KEY key)
|
||
{
|
||
TMask& m = f.mask();
|
||
|
||
if (key == K_TAB && f.to_check(key, true) && m.get(F_NUMDOC).empty() && !f.empty())
|
||
{
|
||
// Mi precarico la dimensione del campo numdoc, cos<6F> in caso di aggiornamenti non devo cambiare
|
||
static const int numdoc_size = TRectype(LF_MOV).length(MOV_NUMDOC);
|
||
|
||
m.set(F_NUMDOC, f.get().right(numdoc_size));
|
||
if (!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().right(numdoc_size), true);
|
||
}
|
||
}
|
||
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.full())
|
||
{
|
||
TRelation occas(LF_OCCAS);
|
||
|
||
occas.curr().put(OCC_CFPI, code);
|
||
if (occas.read(_isequal) == NOERR)
|
||
{
|
||
m.autoload(occas);
|
||
|
||
if (m.field(O_COFI).empty() && !isdigit(code[0]) && cf_check(m.get(O_STATONAS), code))
|
||
m.set(O_COFI, code, 1);
|
||
if (m.field(O_PAIV).empty() && isdigit(code[0]) && pi_check(m.get(O_STATONAS), code))
|
||
m.set(O_PAIV, code, 1);
|
||
|
||
m.send_key(K_TAB, O_COMUNE); // Forza decodifica comuni
|
||
m.send_key(K_TAB, O_COMUNENAS);
|
||
}
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool TPrimanota_application::occas_cfpi_handler(TMask_field& f, KEY key)
|
||
{
|
||
TMask& om = f.mask();
|
||
|
||
if (key == K_TAB && (f.focusdirty() || !om.is_running()))
|
||
{
|
||
TString16 cofi = om.get(O_COFI);
|
||
|
||
if (cofi.empty())
|
||
cofi = om.get(O_CODICE);
|
||
|
||
if (cf_check(om.get(O_STATONAS), cofi))
|
||
{
|
||
int giorno = atoi(cofi.mid(9,2));
|
||
|
||
om.set(O_SESSO, giorno > 40 ? "F" : "M");
|
||
|
||
if (om.field(O_COMUNENAS).empty())
|
||
om.set(O_COMUNENAS, cofi.mid(11,4), 0x2);
|
||
|
||
if (om.field(O_DATANAS).empty())
|
||
{
|
||
const TFixed_string mesi("ABCDEHLMPRST");
|
||
const int mese = mesi.find(cofi[8])+1;
|
||
int anno = atoi(cofi.mid(6,2));
|
||
|
||
if (giorno > 0 && mese > 0 && anno > 0)
|
||
{
|
||
giorno %= 40;
|
||
anno += anno < 5 ? 2000 : 1900;
|
||
om.set(O_DATANAS, TDate(giorno, mese, anno));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
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 TString4 tipo = corri ? " " : app().clifo();
|
||
int gruppo = 0, conto = 0;
|
||
long codice = corri ? 0L : m.get_long(F_CODCLIFOR);
|
||
TSheet_field& ss = cgs();
|
||
const int riga_totale = type2pos(cgrowtype_totale);
|
||
|
||
// 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[0]);
|
||
|
||
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)
|
||
{
|
||
if (riga_totale >= 0) // Dare e Avere potrebbero essere disabilitati
|
||
{
|
||
TToken_string& r = ss.row(riga_totale);
|
||
|
||
if (row_type(r) == cgrowtype_totale)
|
||
{
|
||
r.rtrim(2);
|
||
ss.enable_cell(riga_totale, 0);
|
||
ss.enable_cell(riga_totale, 1);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// Creazione/Aggiornamento riga totale
|
||
TString80 descr;
|
||
if (riga_totale >= 0)
|
||
{
|
||
const int idx_des = ss.cid2index(CG_DESCR);
|
||
|
||
descr = ss.row(riga_totale).get(idx_des);
|
||
}
|
||
if (descr.blank())
|
||
descr = m.get(F_DESCR);
|
||
|
||
TImporto imp = real2imp(m.get_real(F_TOTALE), cgrowtype_totale);
|
||
|
||
set_cgs_row(riga_totale, imp.normalize(), nuovo, descr, cgrowtype_totale);
|
||
}
|
||
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 != nullptr && 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
|
||
{
|
||
TString8 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 TString4 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(F_PIVA); // Partita IVA
|
||
m.show(F_COFI); // 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() && 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 TString& valintra = clifo.get(CLI_VALINTRA);
|
||
|
||
if (valintra.full())
|
||
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.full())
|
||
{
|
||
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(F_PIVA, !occas); // Partita IVA
|
||
m.show(F_COFI, !occas); // Codice Fiscale
|
||
|
||
if (occas && a.is_fattura() && a.partite().first() != nullptr)
|
||
{
|
||
f.warning_box(TR("Attenzione, il saldaconto verr<72> eliminato!"));
|
||
f.set_dirty(); // warning_box cleans the field!
|
||
}
|
||
a.activate_numrif(m, true);
|
||
a.activate_split_payment(m);
|
||
|
||
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
|
||
|
||
TMask_field* ixc = m.find_by_id(F_IVAXCASSA);
|
||
|
||
if (ixc != nullptr)
|
||
{
|
||
TString16 paiv = clifo.get(CLI_PAIV);
|
||
|
||
if (paiv.blank() && occas)
|
||
paiv = a.occas_mask().get(O_PAIV);
|
||
|
||
const int alleg = clifo.get_int(CLI_ALLEG);
|
||
const bool ic = ixc->active() && (alleg < 5 || alleg == 7) && paiv.full() && !m.get_bool(F_LIQDIFF);
|
||
|
||
ixc->set(ic ? "X" : "");
|
||
}
|
||
if(m.get(F_PROKEY).empty() && app().has_module(F1AUT))
|
||
fppro_mask(f, key);
|
||
}
|
||
}
|
||
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 di testa (insert mode only)
|
||
// Certified 99%
|
||
bool TPrimanota_application::main_codiva_handler(TMask_field& f, KEY key)
|
||
{
|
||
static bool __in_handler = false;
|
||
|
||
if (f.mask().mode() == MODE_INS && f.running_check(key))
|
||
{
|
||
if (!__in_handler && f.full() && suspended_handler(f, key))
|
||
{
|
||
TPrimanota_application& a = app();
|
||
TSheet_field & iva = a.ivas();
|
||
int i;
|
||
TString imp;
|
||
|
||
__in_handler = true;
|
||
for (i = iva.items() - 1; i >= 0; i--)
|
||
{
|
||
imp = iva.row(i).get(cid2index(IVA_IMPONIBILE));
|
||
if (imp.full())
|
||
break;
|
||
}
|
||
if (i < 1)
|
||
{
|
||
const real imp(iva.row(0).get(cid2index(IVA_IMPONIBILE)));
|
||
const bool acquisto = a.iva() == iva_acquisti;
|
||
const TCodiceIVA codiva(f.get());
|
||
TMask & mask = f.mask(); // Main mask
|
||
|
||
if (acquisto)
|
||
{
|
||
if (a.causale().intra() && !a.causale().reverse_charge_pubb())
|
||
{
|
||
const real iva = f.mask().get(F_RITFIS); // Le ritenute fiscali vengono usate come IVA intra
|
||
|
||
if (iva.is_zero())
|
||
{
|
||
const real totale = mask.get_real(F_TOTALE);
|
||
const real imposta = codiva.imposta(totale);
|
||
|
||
mask.set(F_RITFIS, imposta, true);
|
||
}
|
||
}
|
||
}
|
||
|
||
TSheet_field & iva = a.ivas();
|
||
TToken_string& row = iva.row(0);
|
||
|
||
const bool corr = a.causale().corrispettivi();
|
||
const bool acq3 = (acquisto) && (codiva.tipo_indetraibilita() == 3 || row.get_int(2) == 3);
|
||
const bool reverse_charge_attivo = acquisto && a.causale().reverse_charge_pubb(); // se la causale e di reverse charge suppongo che il movimento lo sia e quindi metto il flag in ogni caso
|
||
real tot = a.totale_documento(); // Calcola totale documento
|
||
real imposta; // Calcola imposta
|
||
|
||
iva.notify(0, K_SPACE);
|
||
if (!corr && !acq3)
|
||
if (reverse_charge_attivo)
|
||
imposta = codiva.imposta(tot);
|
||
else
|
||
imposta = codiva.scorpora(tot);
|
||
row.add(tot.string(), cid2index(IVA_IMPONIBILE)); // imponibile
|
||
row.add(imposta.string(), cid2index(IVA_IMPOSTA)); // imposta
|
||
row.add(codiva.codice(), cid2index(IVA_CODIVA)); // Aggiorna codice IVA
|
||
if (acquisto)
|
||
{
|
||
row.add(codiva.indetraibilita(), cid2index(IVA_INDETRAIBILE));
|
||
row.add(a.causale().iva() == iva_acquisti && a.causale().reverse_charge_pubb() && reverse_charge_attivo ? "X" : "", cid2index(IVA_REVCHARGE));
|
||
}
|
||
|
||
TBill bill(row, cid2index(IVA_TIPO), 0x1);
|
||
|
||
if (!bill.ok())
|
||
{
|
||
a.IVA2bill(codiva, bill); // Aggiorna conto della prima riga IVA
|
||
bill.add_to(row, cid2index(IVA_TIPOCOSTORIC), 0x7);
|
||
}
|
||
iva.force_update(0);
|
||
iva.notify(0, K_ENTER);
|
||
}
|
||
__in_handler = false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
// Scandisce le righe IVA detraibili e forza il conto corretto in base ai flag IVA in testata
|
||
static void force_iva_det_bill()
|
||
{
|
||
TSheet_field & cgs = app().cgs();
|
||
TMask & mask = cgs.mask();
|
||
const TCausale& cau = app().causale();
|
||
TBill contoiva;
|
||
int ri = 0;
|
||
|
||
if (mask.active(F_LIQDIFF) && mask.get_bool(F_LIQDIFF))
|
||
cau.bill(ri = RIGA_IVA_DIFFERITA, contoiva); else
|
||
if (mask.active(F_IVAXCASSA) && mask.get_bool(F_IVAXCASSA))
|
||
cau.bill(ri = RIGA_IVA_PER_CASSA, contoiva);
|
||
if (ri <= 0 || !contoiva.ok())
|
||
cau.bill(ri = RIGA_IVA_DETRAIBILE, contoiva);
|
||
|
||
TToken_string conto(contoiva.string(0x3));
|
||
const TString80 descragg(cau.desc_agg(ri));
|
||
|
||
FOR_EACH_SHEET_ROW(cgs, r, row)
|
||
{
|
||
const char rtype = row->get_char(cid2index(CG_ROWTYPE));
|
||
|
||
if (rtype == cgrowtype_IVAdet)
|
||
{
|
||
row->add(conto.get(0), cid2index(CG_TIPO));
|
||
row->add(conto.get(), cid2index(CG_GRUPPO));
|
||
row->add(conto.get(), cid2index(CG_CONTO));
|
||
row->add(conto.get(), cid2index(CG_SOTTOCONTO));
|
||
row->add(conto.get(), cid2index(CG_DESCR)); // sc + 1);
|
||
row->add(descragg, cid2index(CG_DESCR));
|
||
}
|
||
}
|
||
cgs.force_update();
|
||
}
|
||
|
||
bool TPrimanota_application::activate_split_payment(TMask& m)
|
||
{
|
||
bool yes = false;
|
||
TMask_field & sp = m.field(F_SPLITPAY);
|
||
|
||
if (clifo() == "C" && m.get_int(F_ANNOIVA) >= 2015 && !causale().reverse_charge_pubb())
|
||
{
|
||
const TRectype& cliente = cache().get_rec(LF_CLIFO, "C", m.get(F_CODCLIFOR));
|
||
|
||
yes = cliente.get_bool(CLI_SPLITPAY);
|
||
}
|
||
if (yes)
|
||
{
|
||
sp.show();
|
||
if (sp.get().blank())
|
||
sp.set("S"); // Set
|
||
}
|
||
else
|
||
{
|
||
sp.hide();
|
||
sp.reset();
|
||
}
|
||
return yes;
|
||
}
|
||
|
||
const TString & TPrimanota_application::clifo() const
|
||
{
|
||
TCausale & caus = causale();
|
||
TBill conto; caus.bill(1, conto);
|
||
TString & tipo = get_tmp_string();
|
||
|
||
tipo << conto.tipo();
|
||
if (tipo.blank())
|
||
tipo = iva() == iva_vendite ? "C" : "F";
|
||
|
||
return tipo;
|
||
}
|
||
|
||
bool TPrimanota_application::is_split_payment() const
|
||
{
|
||
const TMask& m = curr_mask();
|
||
char s = ' ';
|
||
TMask_field* sp = m.find_by_id(F_SPLITPAY);
|
||
|
||
if (sp != nullptr)
|
||
{
|
||
if (sp->shown())
|
||
s = sp->get()[0];
|
||
else
|
||
return false;
|
||
}
|
||
if (s != 'N' && s != 'S')
|
||
{
|
||
s = 'N';
|
||
if (iva() == nessuna_iva)
|
||
return false;
|
||
if (clifo() == "C" && m.get_int(F_ANNOIVA) >= 2015 && !causale().reverse_charge_pubb())
|
||
{
|
||
const TRectype& cliente = cache().get_rec(LF_CLIFO, "C", m.get(F_CODCLIFOR));
|
||
|
||
if (cliente.get_bool(CLI_SPLITPAY))
|
||
{
|
||
TRelation rel(LF_MOV);
|
||
|
||
rel.add(LF_PARTITE, "NREG==NUMREG", 2);
|
||
m.autosave(rel);
|
||
if (::is_split_payment(rel.curr()))
|
||
s = 'S';
|
||
}
|
||
}
|
||
}
|
||
return s == 'S';
|
||
}
|
||
|
||
bool TPrimanota_application::is_fattura_split() const
|
||
{
|
||
return is_fattura() && is_split_payment();
|
||
}
|
||
|
||
// Handler of the F_LIQDIFF
|
||
// Certified 99%
|
||
bool TPrimanota_application::liqdiff_handler(TMask_field& f, KEY key)
|
||
{
|
||
if (key == K_SPACE && f.mask().is_running())
|
||
force_iva_det_bill();
|
||
|
||
if (key == K_ENTER && f.get().full())
|
||
{
|
||
if (f.mask().get_bool(F_IVAXCASSA))
|
||
return f.error_box(TR("Non <20> ammessa IVA per cassa a liquidazione differita"));
|
||
if (app().is_fattura_split())
|
||
return f.error_box(TR("Non <20> ammessa la liquidazione differita con split payment"));
|
||
}
|
||
return true;
|
||
}
|
||
|
||
// Handler of the F_IVAXCASSA
|
||
// Certified 99%
|
||
bool TPrimanota_application::ivaxcassa_handler(TMask_field& f, KEY key)
|
||
{
|
||
const TMask& m = f.mask();
|
||
|
||
if (key == K_SPACE && m.is_running())
|
||
force_iva_det_bill();
|
||
if (key == K_ENTER && f.get().full())
|
||
{
|
||
if (app().is_fattura_split())
|
||
return f.error_box(TR("Non <20> ammessa IVA per cassa con split payment"));
|
||
if (m.get(F_CLIFO) == "C")
|
||
{
|
||
TString8 key; key.format("C|%ld", m.get_long(F_CODCLIFOR));
|
||
const TRectype& clifo = cache().get(LF_CLIFO, key);
|
||
|
||
if (clifo.get_int(CLI_ALLEG) == 6)
|
||
return f.error_box(TR("Non <20> ammessa IVA per cassa con clienti privati"));
|
||
}
|
||
}
|
||
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).full())
|
||
{
|
||
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);
|
||
const real new_totale = cam.val2eur(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);
|
||
const real new_totval = cam.eur2val(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;
|
||
|
||
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 (f.running_check(key))
|
||
{
|
||
a.gioca_cambi();
|
||
if (a.iva() != nessuna_iva)
|
||
{
|
||
a.add_cgs_tot(m);
|
||
if (m.insert_mode()) // Se si e' in inserimento provoca ricalcolo
|
||
{
|
||
TEdit_field & codiva = m.efield(F_CODIVA);
|
||
|
||
codiva.set_focusdirty();
|
||
codiva.on_hit(); // dello sheet iva e delle scadenze
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (a.is_pagamento())
|
||
a.calcola_saldo();
|
||
}
|
||
}
|
||
if (key == K_TAB && a.is_pagamento() && !a._as400)
|
||
{
|
||
m.show(K_RESIDUO, f.get().full());
|
||
m.show(K_TOTALE, f.get().full());
|
||
|
||
}
|
||
if (key == K_ENTER)
|
||
{
|
||
if (a.is_pagamento()&& ! a._as400)
|
||
{
|
||
TImporto importo, totdocsc,tot;
|
||
TSheet_field& cgrows = a.cgs();
|
||
|
||
FOR_EACH_SHEET_ROW_BACK(cgrows, i, r)
|
||
{
|
||
const char tipo = row_type(*r);
|
||
|
||
if (strchr("GK", tipo) != nullptr) // Abbuoni attivi, differenze cambio, spese, ... // (A o P) Abbuoni e (C) Differenze cambio perch<63> c'erano ? non (T) totolae documento perch<63> pagamento
|
||
{
|
||
TImporto importo;
|
||
|
||
importo = *r;
|
||
totdocsc += importo;
|
||
}
|
||
}
|
||
if (tot.valore().is_zero())
|
||
{
|
||
totdocsc.normalize(a.causale().sezione_clifo());
|
||
tot = totdocsc;
|
||
f.set(tot.valore().string());
|
||
a.calcola_saldo();
|
||
}
|
||
}
|
||
|
||
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);
|
||
|
||
if (cambio.in_valuta())
|
||
{
|
||
const real totval(m.get(SK_TOTDOCVAL));
|
||
const TCurrency totlit(cambio.val2eur(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();
|
||
TMask& m = f.mask();
|
||
|
||
a.gioca_cambi();
|
||
if (a.is_fattura() && m.insert_mode())
|
||
a.set_scadenze(m);
|
||
}
|
||
return true;
|
||
}
|
||
|
||
// Aggiunge o aggiorna la riga delle ritenute fiscali o sociali o iva vendite reverse charge
|
||
// Certified 99%
|
||
void TPrimanota_application::add_cgs_ritenute(char tipo)
|
||
{
|
||
if (_as400)
|
||
return;
|
||
|
||
TMask& m = curr_mask();
|
||
const real imp = m.get(tipo== cgrowtype_ritfis ? F_RITFIS : (tipo== cgrowtype_ritsoc ? F_RITSOC : F_REVCHARGE)); // Determina importo
|
||
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 = tipo== cgrowtype_ritfis ? RIGA_RITENUTE_FISCALI : (tipo== cgrowtype_ritsoc ? RIGA_RITENUTE_SOCIALI : RIGA_REVERSE_CHARGE);
|
||
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())
|
||
{
|
||
if (tipo != cgrowtype_revcharge)
|
||
{
|
||
TEdit_field & iva = m.efield(F_CODIVA);
|
||
|
||
iva.set_focusdirty();
|
||
iva.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 100%
|
||
bool TPrimanota_application::ritfis_handler(TMask_field& f, KEY key)
|
||
{
|
||
if (f.running_check(key))
|
||
app().add_cgs_ritenute(cgrowtype_ritfis);
|
||
return true;
|
||
}
|
||
|
||
|
||
// Handler of F_RITSOC
|
||
// Certified 100%
|
||
bool TPrimanota_application::ritsoc_handler(TMask_field& f, KEY key)
|
||
{
|
||
if (f.running_check(key))
|
||
app().add_cgs_ritenute(cgrowtype_ritsoc);
|
||
return true;
|
||
}
|
||
|
||
// Handler of F_REVCHARGE
|
||
// Certified 100%
|
||
bool TPrimanota_application::revcharge_handler(TMask_field& f, KEY key)
|
||
{
|
||
if (f.running_check(key))
|
||
{
|
||
TMask & m = f.mask();
|
||
const bool revcharge = f.get().full();
|
||
|
||
m.enable(F_IVAXCASSA, !revcharge);
|
||
if (revcharge)
|
||
m.set(F_IVAXCASSA, "");
|
||
m.field(F_IVAXCASSA).on_hit();
|
||
}
|
||
else
|
||
if (f.final_check(key))
|
||
{
|
||
const bool revcharge = f.get().full();
|
||
|
||
if (!revcharge)
|
||
return f.error_box(TR("Movimento di reverse charge senza righe di reverse charge"));
|
||
}
|
||
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_DATAINTRA
|
||
// Certified 99%
|
||
bool TPrimanota_application::dataintra_handler(TMask_field& f, KEY key)
|
||
{
|
||
// Se la data INTRA e' vuota allora copiala dalla data di competenza normale
|
||
if (key == K_ENTER && f.empty())
|
||
f.set(f.mask().get(F_DATAREG));
|
||
return true;
|
||
}
|
||
|
||
// 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 (f.running_check(key))
|
||
{
|
||
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(nullptr, 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 != nullptr)
|
||
{
|
||
m.set(F_ANNORIF, game->anno());
|
||
m.set(F_NUMRIF, game->numero());
|
||
}
|
||
}
|
||
else
|
||
{
|
||
bool del = true;
|
||
if (game != nullptr)
|
||
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 contabilit<69>"), false, true);
|
||
TSheet_field& cg = a.cgs();
|
||
|
||
cg.reset_sheet();
|
||
a.add_cgs_tot(m); // Genera totale documento
|
||
if (!m.empty(F_RITFIS))
|
||
a.add_cgs_ritenute(cgrowtype_ritfis); // Genera ritenute fiscali
|
||
if (!m.empty(F_RITSOC))
|
||
a.add_cgs_ritenute(cgrowtype_ritsoc); // 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(i, K_SPACE);
|
||
r = oldrow;
|
||
iva.notify(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;
|
||
}
|
||
|
||
// Handler del bottone di collegamento ai documenti
|
||
bool TPrimanota_application::linkdoc_handler(TMask_field& f, KEY key)
|
||
{
|
||
if (key == K_SPACE)
|
||
{
|
||
const TRectype& mov = app().get_relation()->curr();
|
||
TRectype doc(LF_DOC);
|
||
|
||
doc.put(DOC_PROVV, mov.get(MOV_DPROVV));
|
||
doc.put(DOC_ANNO, mov.get(MOV_DANNO));
|
||
doc.put(DOC_CODNUM,mov.get(MOV_DCODNUM));
|
||
doc.put(DOC_NDOC, mov.get(MOV_DNDOC));
|
||
doc.edit();
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool TPrimanota_application::quadratura_handler(TMask_field& f, KEY key)
|
||
{
|
||
if (key == K_SPACE)
|
||
{
|
||
TMask& m = f.mask();
|
||
TSheet_field& shiva = m.sfield(F_SHEETIVA);
|
||
const real totdoc = app().totale_documento();
|
||
TGeneric_distrib distrib(totdoc, TCurrency::get_firm_dec());
|
||
real totdist;
|
||
|
||
if (!shiva.empty())
|
||
{
|
||
FOR_EACH_SHEET_ROW(shiva, o, orow)
|
||
{
|
||
const real o_imponibile = orow->get(0);
|
||
const real o_imposta = orow->get(3);
|
||
|
||
if (!o_imponibile.is_zero() || !o_imposta.is_zero())
|
||
distrib.add(o_imponibile + o_imposta);
|
||
totdist += o_imponibile + o_imposta;
|
||
}
|
||
}
|
||
if (app()._perc_attesa_fld.full())
|
||
{
|
||
TFieldref f(app()._perc_attesa_fld, LF_CLIFO);
|
||
TRelation cliforel(LF_CLIFO); cliforel.add(LF_CFVEN, "TIPOCF=TIPOCF|CODCF=CODCF");
|
||
TRectype& clifo = cliforel.curr();
|
||
real perc;
|
||
|
||
clifo.put(CLI_TIPOCF, m.get(F_CLIFO));
|
||
clifo.put(CLI_CODCF, m.get(F_CODCLIFOR));
|
||
if (cliforel.read() == NOERR)
|
||
perc = f.read(cliforel);
|
||
real perc_reale = ((totdoc - totdist) * CENTO) / totdist;
|
||
|
||
perc_reale.round(2);
|
||
|
||
if (perc != perc_reale)
|
||
{
|
||
if (!yesno_box("La percentuale su questo documento <20> %s\nmentre dovrebbe essere %s:\nContinuare ugualmente ?", perc_reale.stringa(), perc.stringa()))
|
||
return false;
|
||
}
|
||
}
|
||
FOR_EACH_SHEET_ROW(shiva, n, nrow)
|
||
{
|
||
const real o_imponibile = nrow->get(0);
|
||
const real o_imposta = nrow->get(3);
|
||
|
||
if (!o_imponibile.is_zero() || !o_imposta.is_zero())
|
||
{
|
||
const TString4 zanicchi(nrow->get(1)); // Codice IVA
|
||
const TCodiceIVA i(zanicchi);
|
||
real n_imponibile = distrib.get();
|
||
real n_imposta = i.scorpora(n_imponibile);
|
||
|
||
if (n_imponibile != o_imponibile || n_imposta != o_imposta)
|
||
{
|
||
shiva.notify(n, K_SPACE);
|
||
nrow->add(n_imponibile.string(), 0);
|
||
nrow->add(n_imposta.string(), 3);
|
||
shiva.notify(n, K_ENTER);
|
||
}
|
||
}
|
||
}
|
||
shiva.force_update();
|
||
}
|
||
return true;
|
||
}
|
||
|
||
void TPrimanota_application::write_righe_iva_f1(TMask& cg_msk, const shared_ptr<TPro_msk>& msk)
|
||
{
|
||
TSheet_field& sf = cg_msk.sfield(F_SHEETIVA);
|
||
const vector<TPro_msk::riga_iva_s>& righe = msk->get_righeiva();
|
||
int i = 0;
|
||
|
||
for (auto it = righe.begin(); it != righe.end(); ++it)
|
||
{
|
||
if(it->imponibile != 0 || it->imposta != 0)
|
||
{
|
||
TToken_string& row = sf.row(i);
|
||
|
||
sf.notify(i, K_SPACE);
|
||
row.add(it->imponibile, cid2index(IVA_IMPONIBILE));
|
||
row.add(it->imposta, cid2index(IVA_IMPOSTA));
|
||
row.add(it->aliquota, cid2index(IVA_PERCIVA));
|
||
row.add(it->natura, cid2index(IVA_NATURIVA));
|
||
sf.notify(i, K_ENTER);
|
||
i++;
|
||
}
|
||
}
|
||
}
|
||
bool TPrimanota_application::write_scad_f1(const TMask& cg_msk, const shared_ptr<TPro_msk>& msk)
|
||
{
|
||
TSheet_field& sf = cg_msk.sfield(FS_RATESHEET);
|
||
const int items = sf.items();
|
||
const vector<TPro_msk::scadenza_s>& righe = msk->get_scadenze();
|
||
int i = 0;
|
||
|
||
for (auto it = righe.begin(); it != righe.end(); ++it, ++i)
|
||
{
|
||
TToken_string& row = app().pags().row(i);
|
||
|
||
if(i >= items)
|
||
pag_notify(sf, i, K_CTRL+K_INS);
|
||
pag_notify(sf, i, K_SPACE);
|
||
row.add(it->data, cid2index(101));
|
||
row.add(it->importo, cid2index(102));
|
||
pag_notify(sf, i, K_ENTER);
|
||
}
|
||
return !righe.empty();
|
||
}
|
||
|
||
void TPrimanota_application::write_clifo(TMask& cg_msk, const shared_ptr<TPro_msk>& msk)
|
||
{
|
||
bool ok = false;
|
||
TLocalisamfile clifo(LF_CLIFO);
|
||
TToken_string keys(msk->get_fpprokeys(), ';');
|
||
TString codforn = TFppro(keys).get_codforn();
|
||
|
||
if (codforn.empty())
|
||
codforn = msk->get_codforn();
|
||
if (codforn.empty())
|
||
{
|
||
clifo.setkey(5);
|
||
clifo.put(CLI_TIPOCF, "F");
|
||
clifo.put(CLI_PAIV, msk->get_piva());
|
||
clifo.read();
|
||
ok = clifo.get(CLI_PAIV) == msk->get_piva();
|
||
if(!ok)
|
||
{
|
||
clifo.zero();
|
||
clifo.setkey(5);
|
||
clifo.put(CLI_TIPOCF, "F");
|
||
clifo.put(CLI_PAIV, msk->get_piva());
|
||
clifo.put(CLI_STATOPAIV, "IT");
|
||
clifo.read();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
clifo.setkey(1);
|
||
clifo.put(CLI_TIPOCF, "F");
|
||
clifo.put(CLI_CODCF, codforn);
|
||
clifo.read();
|
||
}
|
||
ok = clifo.get(CLI_PAIV) == msk->get_piva();
|
||
if (ok && (cg_msk.get(F_CODCLIFOR).empty() || cg_msk.get(F_CODCLIFOR) != codforn))
|
||
{
|
||
cg_msk.set(F_CODCLIFOR, clifo.get(CLI_CODCF));
|
||
cg_msk.set(F_RAGSOCCF, clifo.get(CLI_RAGSOC));
|
||
cg_msk.set(F_STATOPAIV, clifo.get(CLI_STATOPAIV));
|
||
cg_msk.set(F_PIVA, clifo.get(CLI_PAIV));
|
||
cg_msk.set(F_COFI, clifo.get(CLI_COFI));
|
||
cg_msk.set(F_CODPAG, clifo.get(CLI_CODPAG));
|
||
TTable tab("%CPG"); tab.put("CODTAB", clifo.get(CLI_CODPAG));
|
||
tab.read();
|
||
cg_msk.set(F_DESPAG, tab.get("S0"));
|
||
}
|
||
}
|
||
|
||
void TPrimanota_application::set_totale(TMask& cg_msk, const shared_ptr<TPro_msk>& msk)
|
||
{
|
||
real totale = msk->get_totdoc();
|
||
|
||
if(totale == ZERO)
|
||
totale = app().calcola_imp();
|
||
|
||
const real rit = msk->get_ritenute();
|
||
|
||
if (rit != ZERO)
|
||
{
|
||
totale -= rit;
|
||
cg_msk.set(F_RITFIS, rit);
|
||
app().add_cgs_ritenute(cgrowtype_ritfis);
|
||
}
|
||
else if (msk->is_doc_split())
|
||
totale = msk->get_tot_imp_riva();
|
||
cg_msk.set(F_TOTALE, totale);
|
||
}
|
||
|
||
void TPrimanota_application::riporta_dati_f1(TMask& cg_msk, const shared_ptr<TPro_msk>& msk)
|
||
{
|
||
const bool bring = msk->should_bring_back();
|
||
|
||
if (bring)
|
||
{
|
||
if (msk->get_numdoc().full() && cg_msk.get(F_CODCLIFOR).empty())
|
||
write_clifo(cg_msk, msk);
|
||
write_righe_iva_f1(cg_msk, msk);
|
||
set_totale(cg_msk, msk);
|
||
cg_msk.set(FS_RECALC, ""); cg_msk.disable(FS_RDIFFER); cg_msk.disable(FS_MCOMM); cg_msk.disable(FS_NRATE);
|
||
if (write_scad_f1(cg_msk, msk))
|
||
app().set_scad_f1(cg_msk);
|
||
}
|
||
// Li riporto anche con il collega in prima nota, e in quel caso solo se i campi non sono gia valorizzati
|
||
if (bring || cg_msk.get(F_NUMDOC).empty())
|
||
{
|
||
cg_msk.set(F_NUMDOCEXT, msk->get_numdoc());
|
||
cg_msk.set(F_NUMDOC, msk->get_numdoc().right(7));
|
||
}
|
||
|
||
if (bring || cg_msk.get(F_DATADOC).empty())
|
||
cg_msk.set(F_DATADOC, msk->get_datadoc());
|
||
}
|
||
|
||
void TPrimanota_application::insert_part_scad(TConfig& ini)
|
||
{
|
||
vector<TToken_string> rif_doc;
|
||
int i = 0;
|
||
ini.set_paragraph("23");
|
||
|
||
// Carico nel vettore
|
||
while(true)
|
||
{
|
||
TToken_string doc("", '|');
|
||
TString str; str << ini.get("NUMLINEA", nullptr, i, "NULL");
|
||
if (str != "NULL")
|
||
{
|
||
doc.add(str);
|
||
doc.add(ini.get("DOCRIF", nullptr, i, "NULL"));
|
||
doc.add(ini.get("DATADOCRIF", nullptr, i, "NULL"));
|
||
|
||
rif_doc.insert(rif_doc.end(), doc);
|
||
i++;
|
||
}
|
||
else
|
||
break;
|
||
}
|
||
|
||
// Agganciare alla partita del documento di riferimento
|
||
if(!rif_doc.empty())
|
||
{
|
||
is_f1() = true;
|
||
|
||
TString query; query << "USE MOV\nSELECT (DATADOC==#DATADOC)";
|
||
TISAM_recordset rec(query);
|
||
rec.set_var("#DATADOC", TVariant(TDate(rif_doc[0].get(2))));
|
||
TString part;
|
||
do
|
||
{
|
||
if (rec.get(MOV_NUMDOC).as_string() == "73/001")
|
||
{
|
||
part = rec.get(MOV_PROTIVA).as_string();
|
||
break;
|
||
}
|
||
} while (rec.move_next());
|
||
|
||
num_doc_rif() = part;
|
||
}
|
||
}
|
||
|
||
bool TPrimanota_application::fppro_mask(TMask_field& f, KEY key)
|
||
{
|
||
TMask& cg_msk = f.mask();
|
||
|
||
if (!app().has_module(FPAUT) || key != K_SPACE && key != K_TAB || !check_causale(cg_msk.get(F_CODCAUS)))
|
||
return true;
|
||
|
||
auto msk = std::make_shared<TPro_msk>(cg_msk);
|
||
|
||
app()._pro_mask = msk;
|
||
|
||
const TString datadoc = cg_msk.get(F_DATADOC);
|
||
|
||
if(datadoc.full())
|
||
{
|
||
msk->set(F_ENABDATE, "X");
|
||
msk->field(F_DATESEARCH).show();
|
||
msk->set(F_DATESEARCH, datadoc);
|
||
}
|
||
if (msk->load_fppro_mask(msk.get()))
|
||
{
|
||
msk->run();
|
||
// Riporto dati FPPRO su maschera Prima Nota (solo se hai F1)
|
||
// Se non hai F1 collego senza riportarti i dati (solo le chiavi db)
|
||
riporta_dati_f1(cg_msk, msk);
|
||
cg_msk.set(F_PROKEY, msk->get_fpprokeys());
|
||
is_collegato(cg_msk.field(F_COLFPPRO));
|
||
cg_msk.set(F_ANNORIF, cg_msk.get(F_ANNOIVA));
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool TPrimanota_application::scollega(const bool set)
|
||
{
|
||
static bool scollega = false;
|
||
|
||
if (set)
|
||
return scollega = true;
|
||
|
||
const bool last = scollega;
|
||
|
||
scollega = false;
|
||
return last;
|
||
}
|
||
|
||
bool TPrimanota_application::scollega_handler(TMask_field& f, KEY key)
|
||
{
|
||
TMask& cg_msk = f.mask();
|
||
|
||
if (!app().has_module(FPAUT) || key != K_SPACE && key != K_TAB || !check_causale(cg_msk.get(F_CODCAUS)))
|
||
return true;
|
||
if (cg_msk.get_bool(F_COLFPPRO))
|
||
{
|
||
scollega(true);
|
||
app().clean_fppro();
|
||
|
||
const bool ok = app().save_dbmov(true);
|
||
|
||
if (ok)
|
||
{
|
||
app().curr_mask().set(F_PROKEY, "");
|
||
app().curr_mask().set(F_COLFPPRO, "");
|
||
}
|
||
message_box("Il movimento e' stato scollegato dalla fattura elettronica\nin ingresso, precedentemente associata.");
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool TPrimanota_application::is_collegato(TMask_field& f)
|
||
{
|
||
TMask& cg_msk = f.mask();
|
||
const bool has_prokey = !cg_msk.get(F_PROKEY).empty();
|
||
|
||
f.set(has_prokey ? "X" : " ");
|
||
return has_prokey;
|
||
}
|
||
|
||
bool TPro_msk::load_fppro_mask(TMask* msk, KEY k)
|
||
{
|
||
// Provo a vedere se hanno l'FP: se c'<27> l'indirizzo controllo che non sia F8 se non c'<27> non hanno l'FP
|
||
if (k != 32)
|
||
return false;
|
||
if (!fp_db().sq_is_connect())
|
||
{
|
||
message_box("Attenzione connessione al database non riuscita.\nImpossibile collegarsi ai documenti in entrata.");
|
||
return false;
|
||
}
|
||
|
||
const int forn = msk->get_int(F_CODCLIFORS);
|
||
|
||
if (forn == 0)
|
||
{
|
||
msk->set(F_ENABSEARCH, "X");
|
||
abilita_piva(msk);
|
||
//message_box("Inserire prima il fornitore");
|
||
//return false;
|
||
}
|
||
|
||
const TString& codfisc = msk->get(F_COFIS);
|
||
const TString& stato_piva = msk->get(F_STATOPAIVS);
|
||
const TString& piva = msk->get(F_PIVAS);
|
||
TString query;
|
||
TString date = "";
|
||
|
||
if (msk->get_bool(F_ENABDATE))
|
||
date = msk->get_date(F_DATESEARCH);
|
||
if(!msk->get_bool(F_ENABSEARCH))
|
||
query = query_fppro(msk->get(F_CODCLIFORS), date);
|
||
else
|
||
query = query_fppro(stato_piva, piva, date);
|
||
fp_db().sq_set_exec(query, false);
|
||
|
||
TSheet_field& sf = msk->sfield(F_SHEETFPPROS);
|
||
|
||
sf.hide();
|
||
if (sf.items() > 0)
|
||
sf.destroy();
|
||
while (fp_db().sq_next())
|
||
{
|
||
TString numreg = fp_db().sq_get("PZ_NUMREGCONT");
|
||
const bool show_all = msk->get_bool(F_SHOWALL);
|
||
|
||
if (numreg != "0" && !show_all)
|
||
continue;
|
||
|
||
TToken_string& row = sf.row(-1);
|
||
TToken_string keys(fp_db().sq_get("PZ_KEYPRGINVIO"), ';');
|
||
|
||
keys.add(fp_db().sq_get("PZ_KEYHEADERFATT")); keys.add(fp_db().sq_get("PZ_KEYBODYFATT"));
|
||
row.add("", 0);
|
||
row.add(fp_db().sq_get("P7_TIPODOC"));
|
||
row.add(TDate(fp_db().sq_get_date("P1_DATAORARIC")));
|
||
row.add(TDate(fp_db().sq_get_date("PZ_DATA")));
|
||
row.add(fp_db().sq_get("PQ_IMPTOTDOC"));
|
||
row.add(fppro_db().set_keys(keys).get_ritenute());
|
||
row.add(fp_db().sq_get("PZ_NUMERO"));
|
||
row.add(fp_db().sq_get("P2_ANADENOMIN"));
|
||
row.add(fp_db().sq_get("P2_FISCIVAPAESE"));
|
||
row.add(fp_db().sq_get("P2_FISCIVACOD"));
|
||
row.add(fp_db().sq_get("P2_CODFISCALE"));
|
||
row.add(fp_db().sq_get("PZ_TIPOPROT"));
|
||
row.add(fp_db().sq_get("PZ_NUMPROT"));
|
||
row.add(keys);
|
||
}
|
||
sf.force_update();
|
||
sf.show();
|
||
return true;
|
||
}
|
||
|
||
bool TPro_msk::fppro_handler(TMask_field& f, KEY k)
|
||
{
|
||
TMask& msk = f.mask();
|
||
|
||
const bool load = load_fppro_mask(&msk, k);
|
||
return load;
|
||
}
|
||
|
||
bool TPro_msk::riporta_handler(TMask_field& f, KEY k)
|
||
{
|
||
if (k != 32)
|
||
return true;
|
||
TMask& msk = f.mask();
|
||
//if (msk.curr_page() != 3)
|
||
//return true;
|
||
bool ok = false;
|
||
TSheet_field& sf = msk.sfield(F_SHEETFPPROS);
|
||
|
||
FOR_EACH_SHEET_ROW(sf, nr, row)
|
||
{
|
||
if(*row->get(0) == 'X')
|
||
{
|
||
//TProtocollo protocollo(TDate(row->get(2)).year(), row->get(9), row->get(10));
|
||
app()._pro_mask->set_doc(row->get(cid2index(F_NUMEROS)), row->get(cid2index(F_DATAS)),
|
||
row->get(cid2index(F_IMPTOTDOCS)), row->get(cid2index(F_RITENUTE)), "", row->get(cid2index(F_KEYFPPROS)),
|
||
msk.get(F_CODCLIFORS), row->get(cid2index(F_FISCIVACODS)));
|
||
if (f.dlg() == DLG_OK)
|
||
app()._pro_mask->_riporta = true;
|
||
else
|
||
app()._pro_mask->_riporta = false;
|
||
ok = true;
|
||
break;
|
||
}
|
||
if(*row->get(0) == 'X')
|
||
row->add("", 0);
|
||
}
|
||
sf.force_update();
|
||
if(!ok)
|
||
message_box("Nessun documento selezionato.");
|
||
msk.stop_run(K_QUIT);
|
||
return true;
|
||
}
|
||
|
||
bool TPro_msk::collega_handler(TMask_field& f, KEY k)
|
||
{
|
||
return riporta_handler(f, k);
|
||
}
|
||
|
||
bool TPro_msk::piva_handler(TMask_field& f, KEY k)
|
||
{
|
||
TMask& msk = f.mask();
|
||
bool ok = true;
|
||
|
||
if(k == K_TAB && f.active() && f.focusdirty())
|
||
{
|
||
ok = load_fppro_mask(&msk, K_SPACE);
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
bool TPro_msk::date_handler(TMask_field& f, KEY k)
|
||
{
|
||
TMask& msk = f.mask();
|
||
bool ok = true;
|
||
|
||
if (k == K_TAB && f.active() && f.focusdirty())
|
||
{
|
||
ok = load_fppro_mask(&msk, K_SPACE);
|
||
}
|
||
return ok;
|
||
}
|
||
|
||
void TPro_msk::fppro_selfatt() const
|
||
{
|
||
const TMask& mask = *this;
|
||
TSheet_field& sf = mask.sfield(F_SHEETFPPROS);
|
||
|
||
sf.hide();
|
||
FOR_EACH_SHEET_ROW(sf, nr, row)
|
||
{
|
||
if (*row->get(0) == 'X')
|
||
row->add("", 0);
|
||
}
|
||
sf.force_update();
|
||
sf.show();
|
||
}
|
||
|
||
bool TPro_msk::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
||
{
|
||
switch (o.dlg())
|
||
{
|
||
case F_SELFPPROS:
|
||
if (e == fe_modify)
|
||
fppro_selfatt();
|
||
break;
|
||
case F_SHOWALL:
|
||
if (e == fe_modify)
|
||
load_fppro_mask(this, K_SPACE);
|
||
break;
|
||
case F_ENABSEARCH:
|
||
if (e == fe_modify)
|
||
{
|
||
abilita_piva(this);
|
||
load_fppro_mask(this);
|
||
}
|
||
break;
|
||
case F_ENABDATE:
|
||
if (e == fe_modify)
|
||
{
|
||
field(F_DATESEARCH).show(o.mask().get_bool(F_ENABDATE));
|
||
if (!o.mask().get_bool(F_ENABDATE))
|
||
load_fppro_mask(this);
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
bool TPro_msk::is_doc_split()
|
||
{
|
||
for(riga_iva_s const& riga : _righe_iva)
|
||
{
|
||
if (riga.esigibilita == 'S')
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
void TPro_msk::set_righeiva(const char* fpprokeys)
|
||
{
|
||
TToken_string keys(fpprokeys, ';');
|
||
TString query;
|
||
|
||
query << "SELECT PL_ALIQUOTAIVA AS ALIQUOTA, PL_NATURA AS NATURA, PL_IMPONIBILE AS IMPONIBILE, PL_IMPOSTA AS IMPOSTA, PL_ESIGIVA AS ESIGIBILITA\nFROM PAA2200F\n" <<
|
||
"WHERE PL_KEYPRGINVIO = '" << keys.get(0) << "' AND PL_KEYHEADERFATT = '" << keys.get(1) << "' AND PL_KEYBODYFATT = '" << keys.get(2) << "';";
|
||
fp_db().sq_set_exec(query, false);
|
||
for(bool ok = fp_db().sq_next(); ok; ok = fp_db().sq_next())
|
||
{
|
||
add_rigaiva(real(fp_db().sq_get("IMPONIBILE")),
|
||
real(fp_db().sq_get("IMPOSTA")),
|
||
real(fp_db().sq_get("ALIQUOTA")),
|
||
fp_db().sq_get("NATURA"),
|
||
fp_db().sq_get("ESIGIBILITA")[0]);
|
||
}
|
||
}
|
||
|
||
void TPro_msk::set_scadenze(const char* fpprokeys)
|
||
{
|
||
TToken_string keys(fpprokeys, ';');
|
||
TString query; query << "SELECT PO_RIGA AS RIGA, PO_DATASCADENZA AS DATA, PO_IMPORTO AS IMPORTO \nFROM PAA2500F \n" <<
|
||
"WHERE PO_KEYPRGINVIO = '" << keys.get(0) << "' AND PO_KEYHEADERFATT = '" << keys.get(1) << "' AND PO_KEYBODYFATT = '" << keys.get(2) << "';";
|
||
|
||
fp_db().sq_set_exec(query, false);
|
||
for(bool ok = fp_db().sq_next(); ok; ok = fp_db().sq_next())
|
||
{
|
||
add_scad(fp_db().sq_get_date("DATA"), real(fp_db().sq_get("IMPORTO")));
|
||
}
|
||
}
|
||
|
||
void TPro_msk::set_doc(const char* numero, const char* datadoc, const char* totdoc, const char* ritenute, const char* protfppro, const char* fpprokeys, const char* codforn, const char* piva)
|
||
{
|
||
_numero = numero;
|
||
_datadoc = datadoc;
|
||
_totdoc = abs(totdoc);
|
||
_ritenute = ritenute;
|
||
_protfppro.sset(protfppro);
|
||
_fpprokeys = fpprokeys;
|
||
_codforn = codforn;
|
||
_piva = piva;
|
||
set_righeiva(fpprokeys);
|
||
set_scadenze(fpprokeys);
|
||
}
|
||
|
||
real TPro_msk::get_tot_imp_riva()
|
||
{
|
||
real tot = ZERO;
|
||
|
||
for(riga_iva_s const& riga : _righe_iva)
|
||
{
|
||
if (riga.imposta > ZERO)
|
||
tot += riga.imponibile;
|
||
}
|
||
return tot;
|
||
}
|
||
|
||
void TPro_msk::add_rigaiva(const real& imponibile, const real& imposta, const real& aliquota, const TString4& natura, char esigib)
|
||
{
|
||
_righe_iva.insert(_righe_iva.end(), { imponibile, imposta, aliquota, natura, esigib });
|
||
}
|
||
|
||
void TPro_msk::add_scad(const TDate& date, const real& importo)
|
||
{
|
||
_scadenze.insert(_scadenze.end(), { date, importo });
|
||
}
|
||
|
||
TString& TPro_msk::query_fppro(const TString& codforn, const TString& date)
|
||
{
|
||
return query_fppro(codforn, "", "", "", date, "", "", "", true, false);
|
||
}
|
||
|
||
TString& TPro_msk::query_fppro(const TString& stato_piva, const TString& piva, const TString& date)
|
||
{
|
||
return query_fppro("", stato_piva, piva, "", date, "", "", "", true, true);
|
||
}
|
||
|
||
TString& TPro_msk::query_fppro(const TString& codforn, const TString& stato_piva, const TString& piva, const TString& where_str, const TString& date, const TString& keyprginvio, const TString& keyheaderfatt, const TString& keybodyfatt, bool order, bool piva_research)
|
||
{
|
||
TString id_fornitore;
|
||
TString keys;
|
||
|
||
if(piva_research && !piva.empty())
|
||
{
|
||
id_fornitore << " (P2_FISCIVAPAESE = ";
|
||
if (!stato_piva.empty())
|
||
id_fornitore << "\'" << stato_piva << "\'";
|
||
else
|
||
id_fornitore << "\'IT\'";
|
||
id_fornitore << " AND P2_FISCIVACOD = \'" << piva << "\') ";
|
||
}
|
||
else
|
||
{
|
||
if(codforn.empty() && !keyprginvio.empty() && !keyheaderfatt.empty() && !keybodyfatt.empty())
|
||
{
|
||
keys << " (PZ_KEYPRGINVIO = '" << keyprginvio << "' AND PZ_KEYHEADERFATT = '" << keyheaderfatt << "' AND PZ_KEYBODYFATT = '" << keybodyfatt << "') ";
|
||
}
|
||
if(!codforn.empty())
|
||
id_fornitore << " (PZ_CLIFOR = '" << codforn << "') ";
|
||
}
|
||
|
||
static TString query;
|
||
query.cut(0) << query_string() << "WHERE ";
|
||
|
||
if (!id_fornitore.empty())
|
||
{
|
||
query << id_fornitore << " ";
|
||
if (!date.empty())
|
||
query << " AND PZ_DATA = '" << TDate(date).date2ansi() << "' ";
|
||
if (order)
|
||
query << "\nORDER BY P1_DATAORARIC ASC";
|
||
query << ";";
|
||
}
|
||
else if (!keys.empty())
|
||
{
|
||
query << keys;
|
||
if (!where_str.empty())
|
||
query << " AND " << where_str;
|
||
query << ";";
|
||
}
|
||
else if (!date.empty())
|
||
{
|
||
query << " PZ_DATA = '" << TDate(date).date2ansi() << "' ";
|
||
if (order)
|
||
query << "\nORDER BY P1_DATAORARIC ASC, PZ_TIPOPROT ASC, PZ_NUMPROT ASC";
|
||
query << ";";
|
||
}
|
||
else
|
||
{
|
||
query.cut(0) << query.left(query.len() - 6);
|
||
query << "\nORDER BY P1_DATAORARIC ASC, PZ_TIPOPROT ASC, PZ_NUMPROT ASC;";
|
||
}
|
||
return query;
|
||
}
|
||
|
||
TString& TPro_msk::query_string()
|
||
{
|
||
static TString query;
|
||
|
||
query.cut(0) << "SELECT PZ_CLIFOR, PZ_DATA, CAST(P1_DATAORARIC AS DATE) AS P1_DATAORARIC, P7_TIPODOC, PQ_IMPTOTDOC, PZ_NUMERO, PZ_NUMREGCONT, PZ_TIPOPROT, " <<
|
||
"PZ_NUMPROT, P2_ANADENOMIN, P2_FISCIVAPAESE, P2_FISCIVACOD, P2_CODFISCALE, PZ_KEYPRGINVIO, PZ_KEYHEADERFATT, PZ_KEYBODYFATT\n" <<
|
||
"FROM PAA0200F \nJOIN FPPRO00F\n" << " ON P2_KEYPRGINVIO = PZ_KEYPRGINVIO AND P2_KEYHEADERFATT = PZ_KEYHEADERFATT AND P2_KEYBODYFATT = PZ_KEYBODYFATT\n" <<
|
||
"JOIN PAA0100F \nON P2_KEYPRGINVIO = P1_KEYPRGINVIO AND P2_KEYHEADERFATT = P1_KEYHEADERFATT AND P2_KEYBODYFATT = P1_KEYBODYFATT\n" <<
|
||
"JOIN PAA2700F \nON P2_KEYPRGINVIO = PQ_KEYPRGINVIO AND P2_KEYHEADERFATT = PQ_KEYHEADERFATT AND P2_KEYBODYFATT = PQ_KEYBODYFATT\n" <<
|
||
"JOIN PAA0700F \nON P7_KEYPRGINVIO = PQ_KEYPRGINVIO AND P7_KEYHEADERFATT = PQ_KEYHEADERFATT AND P7_KEYBODYFATT = PQ_KEYBODYFATT\n";
|
||
return query;
|
||
}
|
||
|
||
void TPro_msk::abilita_piva(TMask* msk)
|
||
{
|
||
if (msk->get_bool(F_ENABSEARCH))
|
||
{
|
||
msk->enable(F_PIVAS);
|
||
msk->enable(F_STATOPAIVS);
|
||
}
|
||
else
|
||
{
|
||
msk->enable(F_PIVAS, false);
|
||
msk->enable(F_STATOPAIVS, false);
|
||
}
|
||
}
|
||
|
||
TPro_msk::TPro_msk(TMask& cg_msk) : TAutomask("cg2100t"), _riporta(false), _codforn("")
|
||
{
|
||
TMask::set_handler(DLG_CONFIG, fppro_handler);
|
||
TMask::set_handler(DLG_OK, riporta_handler);
|
||
if (!app().has_module(F1AUT))
|
||
field(DLG_OK).disable();
|
||
TMask::set_handler(DLG_LINK, collega_handler);
|
||
TMask::set_handler(F_PIVAS, piva_handler);
|
||
TMask::set_handler(F_DATESEARCH, date_handler);
|
||
TMask::set(F_CODCLIFORS, cg_msk.get(F_CODCLIFOR));
|
||
TMask::set(F_COFIS, cg_msk.get(F_COFI));
|
||
TMask::set(F_STATOPAIVS, cg_msk.get(F_STATOPAIV));
|
||
TMask::set(F_PIVAS, cg_msk.get(F_PIVA));
|
||
TMask::set(F_RAGSOCS, cg_msk.get(F_RAGSOCCF));
|
||
set(F_DATESEARCH, TDate(TODAY));
|
||
_righe_iva.clear();
|
||
}
|
||
|
||
bool& is_f1()
|
||
{
|
||
static bool is_f1 = false;
|
||
return is_f1;
|
||
}
|
||
|
||
TString& num_doc_rif()
|
||
{
|
||
static TString num_doc_rif_partite = -1;
|
||
return num_doc_rif_partite;
|
||
} |