campo-sirio/src/cg01/cg2102.cpp
Alex ffc3a8c8ab Patch level : 12.00 1402
Files correlati     : ccg fp ve sy
Commento            :
Patch
2026-01-15 01:17:51 +01:00

4387 lines
120 KiB
C++
Raw Blame History

#include <automask.h>
#include <colors.h>
#include <dongle.h>
#include <execp.h>
#include <golem.h>
#include <isamrpc.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 <pagsca.h>
#include "../fp01/fplib.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();
TImporto i(imp);
i.normalize();
i.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, TImporto& importo,
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);
importo.normalize();
importo.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;
}
void set_importo(TSheet_field & cgrows, int row, const TImporto & imp)
{
TImporto row_imp;
real val = cgrows.get_real_row_cell(row, CG_DARE);
if (val != ZERO)
row_imp.set('D', val);
else
{
val = cgrows.get_real_row_cell(row, CG_AVERE);
if (val != ZERO)
row_imp.set('A', val);
}
row_imp += imp;
row_imp.normalize();
if (row_imp.sezione() == 'D')
{
cgrows.set_row_cell(CG_DARE, row_imp.valore(), row);
cgrows.set_row_cell(CG_AVERE, ZERO, row);
}
else
{
cgrows.set_row_cell(CG_DARE, ZERO, row);
cgrows.set_row_cell(CG_AVERE, row_imp.valore(), row);
}
}
void TPrimanota_application::aggiorna_saldaconto()
{
const bool pag = is_pagamento() && !_as400;
const long nreg = _rel->lfile().get_long(MOV_NUMREG);
int fgruppo = -1;
int fconto = -1;
long fsottoc = -1;
if (pag)
{
TSheet_field& cgrows = cgs();
TAssoc_array rows_index;
FOR_EACH_SHEET_ROW_BACK(cgrows, i, r)
{
const char tipo = row_type(*r);
if ((tipo == cgrowtype_imponibile) ||
(tipo == cgrowtype_spese) ||
(tipo == cgrowtype_abbattivo) ||
(tipo == cgrowtype_diffcambio) ||
(tipo == cgrowtype_abbpassivo) ||
(tipo == cgrowtype_ritfis))
{
cgrows.set_row_cell(CG_DARE, ZERO, i);
cgrows.set_row_cell(CG_AVERE, ZERO, i);
TToken_string key;
TString srow;
srow << i;
key << tipo;
if (tipo == cgrowtype_imponibile)
{
key.add(cgrows.get_int_row_cell(i, CG_GRUPPO));
key.add(cgrows.get_int_row_cell(i, CG_CONTO));
key.add(cgrows.get_long_row_cell(i, CG_SOTTOCONTO));
if (fgruppo < 0)
{
fgruppo = cgrows.get_int_row_cell(i, CG_GRUPPO);
fconto = cgrows.get_int_row_cell(i, CG_CONTO);
fsottoc = cgrows.get_long_row_cell(i, CG_SOTTOCONTO);
}
}
rows_index.add(key, srow);
if (tipo == cgrowtype_imponibile)
{
key.cut(0);
key << tipo;
key.add(0);
key.add(0);
key.add(0);
rows_index.add(key, srow);
}
}
}
TPartite_array & part = partite();
int items = part.items();
TString_array parts;
part.get_keys(parts);
FOR_EACH_ARRAY_ROW(parts, row, key)
{
TPartita & partita = (TPartita &) part[*key];
for (int row = partita.prima_fattura(); row > 0 && row <= partita.last(); row = partita.succ(row))
{
const TRiga_partite & rpart = partita.riga(row);
if (rpart.is_fattura())
{
const int nrate = rpart.rate();
for (int s = 1; s <= nrate; s++)
{
const TRiga_scadenze & scad = rpart.rata(s);
int rp = scad.last();
for (; rp > 0; rp = scad.pred(rp))
{
TRectype & pag = (TRectype &) scad.row(rp);
int rpag = pag.get_int(PAGSCA_NRIGP);
if (partita.exist(rpag))
{
TRiga_partite & riga_pag = partita.riga(rpag);
const long nreg_pag = riga_pag.get_long(PART_NREG);
if (nreg == nreg_pag)
{
char sez = pag.get(PAGSCA_TIPOC) == "C" ? 'D' : 'A';
real val = pag.get_real(PAGSCA_IMPORTO);
if (val != ZERO)
{
TImporto imp(sez, val);
TToken_string key;
const int gruppo = pag.get_int(PAGSCA_GRUPPOC);
key << (char)cgrowtype_imponibile;
key.add(gruppo);
key.add(pag.get_int(PAGSCA_CONTOC));
key.add(pag.get_long(PAGSCA_SOTTOCONTC));
if (rows_index.is_key(key))
set_importo(cgrows, rows_index.get_int(key), imp);
if (gruppo <= 0 && fgruppo > 0)
{
pag.put(PAGSCA_GRUPPOC, fgruppo);
pag.put(PAGSCA_CONTOC, fconto);
pag.put(PAGSCA_SOTTOCONTC, fsottoc);
}
}
val = pag.get_real(PAGSCA_ABBUONI);
bool attivo = pag.get_real(PAGSCA_PASSATT) == "A";
if (val != ZERO)
{
TImporto imp(sez, val);
TToken_string key;
key << (char)(attivo ? cgrowtype_abbattivo : cgrowtype_abbpassivo);
if (rows_index.is_key(key))
set_importo(cgrows, rows_index.get_int(key), imp);
}
val = pag.get_real(PAGSCA_DIFFCAM);
if (val != ZERO)
{
TImporto imp(sez, val);
TToken_string key;
key << (char)cgrowtype_diffcambio;
if (rows_index.is_key(key))
set_importo(cgrows, rows_index.get_int(key), imp);
}
val = pag.get_real(PAGSCA_RITENUTE);
if (val != ZERO)
{
TImporto imp(sez, val);
TToken_string key;
key << (char)cgrowtype_ritfis;
if (rows_index.is_key(key))
set_importo(cgrows, rows_index.get_int(key), imp);
}
val = pag.get_real(PAGSCA_RITSOC);
if (val != ZERO)
{
TImporto imp(sez, val);
TToken_string key;
key << (char)cgrowtype_ritsoc;
if (rows_index.is_key(key))
set_importo(cgrows, rows_index.get_int(key), imp);
}
}
}
}
}
}
}
TRecord_array & unas = partita.unassigned();
if (unas.rows() > 0)
{
for (int r = unas.last_row(); r > 0; r = unas.pred_row(r))
{
const TRectype & pag = unas.row(r);
int rpag = pag.get_int(PAGSCA_NRIGP);
if (partita.exist(rpag))
{
TRiga_partite & riga_pag = partita.riga(rpag);
const long nreg_pag = riga_pag.get_long(PART_NREG);
if (nreg == nreg_pag)
{
char sez = pag.get(PAGSCA_TIPOC) == "C" ? 'D' : 'A';
real val = pag.get_real(PAGSCA_IMPORTO);
if (val != ZERO)
{
TImporto imp(sez, val);
TToken_string key;
key << (char)cgrowtype_imponibile;
key.add(pag.get_int(PAGSCA_GRUPPOC));
key.add(pag.get_int(PAGSCA_CONTOC));
key.add(pag.get_long(PAGSCA_SOTTOCONTC));
if (rows_index.is_key(key))
set_importo(cgrows, rows_index.get_int(key), imp);
}
}
}
}
}
}
cgrows.force_update();
}
}
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, 9, 0x1);
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();
m.set(IVA_PERCIVA, iva.percentuale());
m.set(IVA_NATURIVA, iva.natura());
}
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
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 (tipocf == "C")
{
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.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;
}
// 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.initial_check(key))
{
TMask& m = f.mask();
const int ann = m.get_int(F_ANNOIVA);
const TString& cau = f.get();
const TCausale & c = cached_causale(cau, ann);
m.enable_single_page(app()._xml_page, c.is_reg_sdi());
}
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 = cached_causale(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" : " ");
const TString & prefisso = c.reg().prefisso();
if (prefisso.full())
{
m.show(F_PREFISSO);
m.show(F_SLASH);
m.set(F_PREFISSO, prefisso);
}
else
{
m.hide(F_PREFISSO);
m.hide(F_SLASH);
m.reset(F_PREFISSO);
}
}
new_mask->enable_single_page(app()._xml_page, c.is_reg_sdi());
}
}
}
}
else
return false;
}
else
if (f.initial_check(key))
{
TMask& m = f.mask();
const int ann = m.get_int(F_ANNOIVA);
const TString& cau = f.get();
if (cau.full())
{
const TCausale & c = cached_causale(cau, ann);
if (c.iva() != nessuna_iva)
{
const TString & prefisso = c.reg().prefisso();
if (prefisso.full())
{
m.show(F_PREFISSO);
m.show(F_SLASH);
m.set(F_PREFISSO, prefisso);
}
else
{
m.hide(F_PREFISSO);
m.hide(F_SLASH);
m.reset(F_PREFISSO);
}
}
}
}
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);
}
}
}
}
}
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 TString8 cod_reg = m.get(F_CODREG);
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();
const TString8 cr = rec.get(MOV_REG);
if (ad == annodoc && cod_reg == cr)
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();
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
TString4 tipocorr = rowt.get(2);
if (tipocorr.full())
tipo = tipocorr;
}
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, 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" : "");
}
}
}
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));
}
row.add(codiva.percentuale(), cid2index(IVA_PERCIVA));
row.add(codiva.natura(), cid2index(IVA_NATURIVA));
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))
{
bool revcharge = f.get().full();
if (!revcharge)
{
TSheet_field& sheet_iva = f.mask().sfield(F_SHEETIVA);
const int row = sheet_iva.items();
for (int r = 0; !revcharge && r< row; r++)
{
revcharge |= sheet_iva.get_bool_row_cell(r, IVA_REVCHARGE);
}
}
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.full() && TCurrency::get_firm_val() != codval)
{
const TRectype & cam =cache().get("CAM", codval);
if (cam.full())
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();
m.enable_single_page(2, page);
if (page != m.page_enabled(2))
{
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;
}
bool TPrimanota_application::genera_xml_handler(TMask_field& f, KEY key)
{
if (key == K_SPACE)
{
TMask& m = (TDocumento_mask&)f.mask();
TString prg_invio = m.get(F_PRG_INVIO);
TMovimento_contabile mov(m.get_long(F_NUMREG));
if (m.dirty())
return error_box("Registrare il documento per generare l'xml");
mov.generate_xml();
if (prg_invio.blank())
{
prg_invio = mov.get(MOV_PRG_INVIO);
m.set(F_PRG_INVIO, prg_invio);
m.set(F_XML_NAME, mov.get(MOV_XML_NAME));
}
m.set(F_STATO_SDI, mov.get(MOV_STATO_SDI));
const TString & esito = m.get(F_STATO_SDI); // "|Da generare X|Da inviare I|Inviate C|Consegnate E|In errore D|Diag.
m.enable(DLG_XML_PREVIEW, prg_invio.full());
m.enable(DLG_PDF_PREVIEW, prg_invio.full());
m.enable(DLG_CHECK_SDI, fp_has_check() && prg_invio.full() && esito == "X");
m.enable(DLG_INVIO_SDI, prg_invio.full() && esito == "X");
m.enable(DLG_ESITO_SDI, prg_invio.full() && esito == "C" && esito == "E");
}
return true;
}
HIDDEN TString & get_xml_filename(bool ven, int anno, const char * xml_filename)
{
TFilename name;
name = get_xml_dest(ven, anno);
name.add(xml_filename);
name.ext("xml");
return get_tmp_string() << name;
}
bool TPrimanota_application::vis_xml_handler(TMask_field& f, KEY key)
{
if (key == K_SPACE)
{
TMask& mask = (TMask &)f.mask();
TFilename name = get_xml_filename(true, mask.get_int(F_ANNOES), mask.get(F_XML_NAME));
if (name.exist())
goto_url(name);
}
return true;
}
bool TPrimanota_application::invia_xml_handler(TMask_field& f, KEY key)
{
if (key == K_SPACE)
{
TMask & mask = (TMask &)f.mask();
TMovimento_contabile mov(mask.get_long(F_NUMREG));
mov.send_xml();
mask.set(F_STATO_SDI, mov.get(MOV_STATO_SDI));
}
return true;
}
bool TPrimanota_application::vis_pdf_handler(TMask_field& f, KEY key)
{
if (key == K_SPACE)
{
TMask& mask = (TMask &)f.mask();
int anno = mask.get_int(F_ANNOES);
TFilename name = get_xml_filename(true, mask.get_int(F_ANNOES), mask.get(F_XML_NAME));
if (name.exist())
{
int stile = 0;
TFilename style = mask.get(F_STILE_SDI);
TToken_string codes = mask.lfield(F_STILE_SDI).get_codes();
FOR_EACH_STR_TOKEN(codes, code)
if (style == code)
break;
else
stile++;
TFilename out = get_pdf_dest(stile, anno);
out.add(name.name_only());
out.ext("html");
int err = xslt_transform(name, style, out);
if (err != 0)
{
TString msg = TR("Errore nella generazione del PDF : ");
if (err == 1)
msg << "XML assente o errato";
else
if (err == 2)
msg << "foglio di stile assente";
else
if (err == 3)
msg << "nessun output";
return error_box(msg);
}
html2pdf(out);
out.fremove();
out.ext("pdf");
goto_url(out);
}
}
return true;
}
#define MAX_SIZE 4096
HIDDEN int get_resp_prop(const char * prop, TString & val, const TString & response, int startpos = 0)
{
val.cut(0);
int pos = response.find(prop);
int stop = 0;
if (pos > 0)
{
pos += 2;
stop = response.find("\"", pos);
if (stop > 0)
stop--;
val = response.mid(pos, stop - pos);
}
return stop;
}
bool TPrimanota_application::check_sdi_handler(TMask_field& f, KEY key)
{
if (key == K_SPACE)
{
TMask& mask = (TMask &)f.mask();
TMovimento_contabile mov(mask.get_long(F_NUMREG));
if (mov.check())
mask.set(F_STATO_SDI, "D");
}
return true;
}
bool TPrimanota_application::esito_sdi_handler(TMask_field& f, KEY key)
{
if (key == K_SPACE)
{
TDocumento_mask& mask = (TDocumento_mask &)f.mask();
TFilename name = get_xml_dest();
name.add(mask.get(F_XML_NAME));
name.ext("xml");
}
return true;
}
void TPrimanota_application::insert_part_scad(TConfig& ini) // che cazzo significa la partita 73/001
{
TArray rif_doc;
TString str = ini.get("NUMLINEA", "23", 0);
// Carico nel vettore
for (int i = 0; str.full(); str = ini.get("NUMLINEA", "23", ++i))
{
TToken_string doc("", '|');
doc.add(str);
doc.add(ini.get("DOCRIF", "23", i));
doc.add(ini.get("DATADOCRIF", "23", i));
rif_doc.add(doc);
}
// Agganciare alla partita del documento di riferimento
if(rif_doc.items() > 0)
{
TString query; query << "USE MOV\nSELECT (DATADOC==#DATADOC)";
TISAM_recordset rec(query);
TString part;
FOR_EACH_ARRAY_ITEM(rif_doc, r, _obj)
{
if (part.blank())
{
rec.set_var("#DATADOC", ((TToken_string&)rif_doc[0]).get_date(2));
for (bool ok = rec.move_first(); ok; ok = rec.move_next())
{
if (rec.get_string(MOV_NUMDOC) == "73/001")
{
part = rec.get_string(MOV_PROTIVA);
break;
}
} while (rec.move_next());
}
}
_num_doc_rif_partite = part;
}
}