campo-sirio/cg/cg2100.cpp
guy ff1776e668 Patch level : 10.0
Files correlati     : cg3
Ricompilazione Demo : [ ]
Commento            :
Rimodernate maschere contabilita'


git-svn-id: svn://10.65.10.50/trunk@18319 c028cbd2-c16b-5b4b-a496-9718f37d4682
2009-02-23 11:43:21 +00:00

2176 lines
62 KiB
C++
Executable File

#include "cg2102.h"
#include "cg21sld.h"
#include "cgpagame.h"
#include "../ca/movana.h"
#include "../in/inlib01.h"
#include <execp.h>
#include <mailbox.h>
#include <modaut.h>
#include <urldefid.h>
#include <utility.h>
// Campi su file
#include <clifo.h>
#include <cfven.h>
#include <rcausali.h>
// Campi su maschera
#include "cg2100.h"
///////////////////////////////////////////////////////////
// Dati incasso immediato
///////////////////////////////////////////////////////////
class TDati_mov_auto : public TObject
{
public:
int _tipo, _step;
TString4 _causale, _codiva;
TBill _clifo;
TDate _datadoc;
TString8 _numdoc;
real _totale;
TString4 _causale_fattura;
TipoIVA _iva_fattura;
};
///////////////////////////////////////////////////////////
// Applicazione principale
///////////////////////////////////////////////////////////
TPrimanota_application::TPrimanota_application()
: _rel(NULL), _mode(0), _iva(nessuna_iva), _causale(NULL), _giornale(NULL),
_lastreg(0), _last_dreg(TODAY), _last_dcom(TODAY), _automatico(NULL), _swap_mask(false)
{
memset(_msk, 0, sizeof(_msk));
}
TMask* TPrimanota_application::load_mask(int n)
{
if (_msk[n] != NULL)
return _msk[n];
TString8 name = "cg2100"; name << char(n == 3 ? 'o' : 'a'+n);
TMask* m = new TMask(name);
switch (n)
{
case 0:
if (m)
{
m->set_handler(F_NUMREG, num_handler);
m->set_handler(F_CODCAUS, caus_query_handler);
m->set_handler(F_DATAREG, datareg_handler);
TConfig c(CONFIG_STUDIO, "cg");
// Scelta primo campo col focus
_firstfocus = c.get_bool("PoCuDr") ? F_DATAREG : F_CODCAUS;
m->first_focus(_firstfocus);
// Registra e inserisci immediatamente un nuovo movimento
_savenew = !c.get_bool("Cg21SN");
}
break;
case 2:
if (m)
{
m->set_handler(F_DATA74TER, data74ter_handler);
m->set_handler(F_PROTIVA, protiva_handler);
m->set_handler(F_CLIENTE, clifo_handler);
m->set_handler(F_FORNITORE, clifo_handler);
m->set_handler(F_RITFIS, ritfis_handler);
m->set_handler(F_RITSOC, ritsoc_handler);
m->set_handler(F_CORRISPETTIVO, corrlire_handler);
m->set_handler(F_CORRVALUTA, corrvaluta_handler);
m->set_handler(F_DATAINTRA, dataintra_handler);
m->set_handler(F_CODIVA, main_codiva_handler);
m->set_handler(F_OCCASEDIT, occas_handler);
m->set_handler(F_SOLAIVA, solaiva_handler);
m->set_handler(F_SHEETIVA, iva_handler);
TSheet_field& is = m->sfield(F_SHEETIVA);
is.set_notify(iva_notify);
TMask& ism = is.sheet_mask();
ism.set_handler(101, imponibile_handler);
ism.set_handler(102, codiva_handler);
ism.set_handler(103, detrazione_handler);
ism.set_handler(104, imposta_handler);
ism.set_handler(107, cg_gruppo_handler);
ism.set_handler(109, iva_sottoconto_handler);
ism.set_handler(110, iva_sottoconto_handler);
ism.set_handler(209, sheet_clifo_handler);
ism.set_handler(309, sheet_clifo_handler);
if (_quadratura)
m->set_handler(F_ADJUST_IVA, quadratura_handler);
}
case 1:
if (m)
{
m->first_focus(_firstfocus);
m->set_handler(F_DATAREG, datareg_handler);
m->set_handler(F_DATACOMP, datacomp_handler);
m->set_handler(F_DATADOC, datadoc_handler);
m->set_handler(F_NUMDOC, numdoc_handler);
m->set_handler(F_DESCR, descr_handler);
m->set_handler(F_CODCAUS, caus_modify_handler);
m->set_handler(F_TOTALE, totdoc_handler);
m->set_handler(F_SHEETCG, cg_handler);
m->set_handler(SK_VALUTA, valuta_handler);
m->set_handler(SK_DATACAMBIO, datacambio_handler);
m->set_handler(SK_CAMBIO, cambio_handler);
m->set_handler(SK_TOTDOCVAL, totdocval_handler);
m->set_handler(F_CODPAG, codpag_handler);
m->set_handler(F_LINKDOC, linkdoc_handler);
m->set_handler(F_MASTRINO, mastrino_handler);
TSheet_field& cg = m->sfield(F_SHEETCG);
cg.set_notify(cg_notify);
TMask& cgm = cg.sheet_mask();
cgm.set_handler(CG_DARE, dareavere_handler);
cgm.set_handler(CG_AVERE, dareavere_handler);
// cgm.set_handler(CG_TIPO, cg_tipo_handler);
cgm.set_handler(CG_GRUPPO, cg_gruppo_handler);
cgm.set_handler(CG_CONTO, cg_conto_handler);
cgm.set_handler(CG_SOTTOCONTO, cg_sottoconto_handler);
cgm.set_handler(CG_SOTTOCONTO + 100, sheet_clifo_handler);
cgm.set_handler(CG_SOTTOCONTO + 200, sheet_clifo_handler);
cgm.set_handler(113, suspended_handler); // Contropartita
cgm.set_handler(213, sheet_clifo_handler);
cgm.set_handler(313, sheet_clifo_handler);
cgm.set_handler(CG_MASTRINO, sheet_mastrino_handler);
// Se esiste lo sheet delle rate
if (is_fattura())
{
TSheet_field& ps = m->sfield(FS_RATESHEET);
ps.set_notify(pag_notify);
m->set_handler(FS_RATESHEET, pag_sheet_handler);
m->set_handler(F_ANNORIF, annorif_handler);
m->set_handler(F_NUMRIF, numrif_handler);
m->set_handler(FS_RESET, reset_handler);
m->set_handler(FS_NRATE, nrate_handler);
m->set_handler(FS_RECALC, recalc_handler);
m->set_handler(FS_NSCAB, codcab_handler);
m->set_handler(FS_VSCAB, codcab_handler);
TMask& sm = ps.sheet_mask();
sm.set_handler(102, ratalit_handler);
sm.set_handler(103, rataval_handler);
sm.set_handler(105, tipopag_handler);
sm.set_handler(106, tipopag_handler);
}
}
break;
case 3:
m->set_handler(O_CODICE, occas_code_handler);
m->set_handler(O_COFI, occas_cfpi_handler);
m->set_handler(O_PAIV, occas_cfpi_handler);
break;
default:
CHECKD(0, "Che ca$$o di maschera e' la ", n);
break;
}
_msk[n] = m;
return m;
}
bool TPrimanota_application::user_create()
{
open_files(LF_TABCOM, LF_TAB, LF_CAUSALI, LF_RCAUSALI, LF_CLIFO, LF_PCON, 0);
open_files(LF_ATTIV, LF_COMUNI, LF_OCCAS, LF_NDITTE, 0);
open_files(LF_MOV, LF_RMOV, LF_RMOVIVA, LF_SALDI, 0);
open_files(LF_PARTITE, LF_SCADENZE, LF_PAGSCA, LF_AGENTI, 0);
_automatico = new TDati_mov_auto;
_rel = new TMovimentoPN;
_rel->add(LF_PARTITE, "NREG=NUMREG", 2); // Collega la partita aperta dalla fattura
_causale = new TCausale();
_giornale = new TLibro_giornale();
set_search_field(F_NUMREG); // Set field for default search
_pag = NULL;
_is_saldaconto = false;
TFilename tmp;
if (get_mask_swap_file(tmp))
tmp.fremove();
load_mask(0);
load_colors();
return true;
}
bool TPrimanota_application::save_and_new() const
{
return _savenew || _automatico->_step == 1;
}
bool TPrimanota_application::user_destroy()
{
for (int m = 3; m >= 0; m--)
if (_msk[m] != NULL) delete _msk[m];
if (_pag) delete _pag;
delete _giornale;
delete _causale;
delete _rel;
delete _automatico;
return true;
}
// Legge la causale di codice cod ed il relativo registro dell'anno year
// Certified 99%
bool TPrimanota_application::read_caus(const char* cod, int year)
{
bool ok = true;
if (cod != NULL)
ok = causale().read(cod, year);
bool nob = false, dob = false;
_is_saldaconto = false;
const TipoIVA iva = ok ? causale().iva() : nessuna_iva;
TMask* m = _msk[iva == nessuna_iva ? 1 : 2];
const TDate datareg = m ? m->get(F_DATAREG) : _rel->curr().get(MOV_DATAREG);
if (ok)
{
_is_saldaconto = gestione_saldaconto() && causale().saldaconto(datareg);
dob = is_fattura() || causale().data_doc();
nob = is_fattura() || causale().num_doc();
}
// Se sono chiamato dai campi di query ho belle che finito
if (_mode == MODE_QUERY || m == NULL)
return true;
const bool ins = m->insert_mode();
m->efield(F_NUMDOC).check_type(nob ? CHECK_REQUIRED : CHECK_NORMAL); // Num. doc. obbligatorio
m->efield(F_DATADOC).check_type(dob ? CHECK_REQUIRED : CHECK_NORMAL); // Data doc. obbligatoria
const bool nota_credito = is_nota_credito();
const bool show_games = is_pagamento() || nota_credito;
TSheet_field& cgsheet = m->sfield(F_SHEETCG);
TMask& cgm = cgsheet.sheet_mask();
cgm.set_handler(DLG_USER, show_games ? showpartite_handler : NULL); // bottoncino riga
cgm.enable(DLG_USER, show_games);
if (iva == nessuna_iva)
{
m->enable(F_PROVVISORIO, !_is_saldaconto); // Il saldaconto vieta i movimenti provvisori
m->show(SK_TIPORIGA, is_pagamento()); // Abilita scelta tipo riga
m->enable(SK_TIPORIGA);
activate_numrif(*m, false);
}
else
{
m->efield(F_CODPAG).enable(!nota_credito);
m->efield(F_DESPAG).enable(!nota_credito);
TEdit_field& numrif = m->efield(F_NUMRIF);
numrif.set_justify(iva == iva_acquisti ? _num_for : _num_cli);
numrif.set_trim(!numrif.right_justified());
activate_numrif(*m, false);
const TCausale & c = causale();
const bool av = c.reg().agenzia_viaggi();
m->show(F_DATA74TER, av);
if (!av) m->reset(F_DATA74TER);
const TRegistro & r = c.reg();
const bool reg_vendite = r.iva() == iva_vendite && !r.corrispettivi();
const bool liqdiff = _liqdiff && c.liqdiff()&& reg_vendite;
m->show(F_DATAINC, liqdiff);
if (!liqdiff) m->reset(F_DATAINC);
if (ins)
{
const long protiva = causale().reg().protocol() + 1;
m->set(F_PROTIVA, protiva, true); // Aggiorna protocollo IVA
}
const bool show_notevar = iva == iva_vendite || iva == iva_acquisti;
TSheet_field& ivasheet = m->sfield(F_SHEETIVA);
ivasheet.enable_column(IVA_NOTAVARECF, show_notevar);
ivasheet.sheet_mask().enable(IVA_NOTAVARECF, show_notevar);
}
if (ins && !ci_sono_importi())
{
cgsheet.reset();
for (int i = 1; i < causale().size(); i++)
{
const TRectype* rcaus = (TRectype*)causale().objptr(i);
if (rcaus == NULL) continue; // Evita eventuali righe nulle
const int nriga = rcaus->get_int(RCA_NRIGA);
if (nriga <= 0) continue; // Considera solo righe reali (non riempimenti)
TBill tc; causale().bill(nriga, tc);
if (tc.gruppo() <= 0) continue; // Considera solo gruppi validi
if (tc.tipo() > ' ' && tc.ok())
{
TBill clifo(0, 0, tc.sottoconto(), tc.tipo());
if (clifo.find() && clifo.conto() != 0) // Legge gruppo e conto
tc = clifo;
}
int err = 0;
if (tc.descrizione() == TR("Sconosciuto"))
err = 1; else
if (tc.sospeso())
err = 2;
if (err)
{
error_box(FR("Il conto della riga %d della causale e' %s"),
i, err == 1 ? TR("sconosciuto") : TR("sospeso"));
}
const char sezione = rcaus->get_char(RCA_SEZIONE);
const TImporto zero('D', ZERO);
const TString80 desc(causale().desc_agg(i));
if (nriga == 1) m->set(F_DESCR, desc);
if (iva == nessuna_iva)
{
char tipr = ' ';
if (is_pagamento())
{
if (nriga <= RIGA_PAG_RITSOC && nriga != RIGA_SPESE)
continue; // Si considerano solo le spese
tipr = 'G';
}
const int pos = set_cgs_row(-1, zero, tc, desc, tipr);
if (sezione > ' ')
cgsheet.disable_cell(pos, sezione == 'A' ? 0 : 1);
}
else
{
if (nriga >= 2 && nriga <= 9)
continue; // Conti per IVA detraibile e non, ritenute sociali e fiscali
const char tipo = nriga == 1 ? 'T' : ' ';
if (nriga == 1 && tc.tipo() > ' ' && tc.ok())
{
m->set(tc.tipo() == 'C' ? F_CLIENTE : F_FORNITORE, tc.sottoconto());
}
set_cgs_row(-1,zero,tc,desc,tipo);
}
}
fill_sheet(*m);
}
return ok;
}
// Certified 100%
void TPrimanota_application::print()
{
TExternal_app stampa("cg3 -0");
stampa.run();
}
bool TPrimanota_application::menu(MENU_TAG mt)
{
bool ok = true;
if (mt == MENU_ITEM_ID(1))
set_colors();
else
ok = TRelation_application::menu(mt);
return ok;
}
bool TPrimanota_application::changing_mask(int mode)
{
if (mode == MODE_QUERY)
{
const bool flag = _mode != MODE_QUERY;
return flag;
}
_iva = iva_errata;
return true;
}
TMask* TPrimanota_application::get_mask(int mode)
{
int annoiva = 0;
TString4 caus;
_mode = mode;
switch (mode)
{
case MODE_INS:
annoiva = _msk[0]->get_int(F_ANNOIVA);
caus = _msk[0]->get(F_CODCAUS);
break;
case MODE_MOD:
annoiva = _rel->curr().get_int(MOV_ANNOIVA);
caus = _rel->curr().get(MOV_CODCAUS);
break;
default:
return load_mask(0);
}
if (giornale().year() != annoiva)
giornale().read(annoiva);
const TCausale& c = causale();
if (caus != c.codice() || (c.iva() != nessuna_iva && c.reg().year() != annoiva))
read_caus(caus, annoiva);
_iva = c.iva();
return load_mask(_iva == nessuna_iva ? 1 : 2);
}
bool TPrimanota_application::get_mask_swap_file(TFilename& name) const
{
name.tempdir(); name.add("cg2100.ini");
return name.exist();
}
bool TPrimanota_application::force_mask_swap(const TCausale& old_caus, const TCausale& new_caus)
{
TMask& old = curr_mask();
// Resetto il flag di dirty per non chiedere di salvare cose inutili
for (int i = old.fields()-1; i >= 0; i--)
{
TMask_field& f = old.fld(i);
f.set_dirty(false);
}
if (old.dirty())
return false;
// Salvo la maschera corrente in un apposito file temporaneo "cg2100.ini"
TFilename tmp; get_mask_swap_file(tmp);
TConfig ini(tmp);
TRelation_application::mask2ini(old, ini); // Non devo salvare le righe degli sheet
ini.set_paragraph("23");
ini.remove(MOV_NUMREG); // Tolgo numero di registrazione provvisorio
if (old_caus.iva() != nessuna_iva && new_caus.iva() != nessuna_iva)
{
// Salvo un campo virtuale col codice IVA
ini.set("CODIVA", old.get(F_CODIVA)); // Campo virtuale non presente in testata
}
if (old_caus.iva() != new_caus.iva() || old_caus.corrispettivi() != new_caus.corrispettivi())
{
ini.remove(MOV_CODCF); // Tolgo il codice cliente, che potrebbe infornitorirsi
}
ini.remove(MOV_PROVVIS);
_swap_mask = true;
old.stop_run(K_ESC);
return true;
}
void TPrimanota_application::on_firm_change()
{
TRelation_application::on_firm_change(); // May be useful, who knows?
_lastreg = 0;
if (_rel->lfile().last() == NOERR)
_lastreg = _rel->curr().get_long(MOV_NUMREG); // Init last registration number
_esercizi.update(); // Init exercises
}
void TPrimanota_application::on_config_change()
{
TConfig cnf(CONFIG_DITTA, "cg");
_ges_val = cnf.get_bool("GesVal");
_ges_sal = cnf.get_bool("GesSal");
_npart_is_prot = cnf.get_bool("RifPro");
_liqdiff = cnf.get_bool("GesLiqDiff");
_num_cli = cnf.get_bool("NrCliDx");
_num_for = cnf.get_bool("NrForDx");
_quadratura = cnf.get_bool("QuadraturaIVA"); // Accende bottone di quadratura
_perc_attesa_fld = cnf.get("PercAttField");
TPartita::carica_allineamento();
}
void TPrimanota_application::init_mask(TMask& m)
{
disable_menu_item(M_FILE_PRINT);
disable_menu_item(M_FONT);
read_caus(NULL, 0); // Setta campi obbligatori
if (_iva == nessuna_iva)
{
m.show(-5, _is_saldaconto); // Abilita campi saldaconto
m.show(-6, _is_saldaconto && is_fattura()); // Abilita gestione rate
m.show(K_RESIDUO, _is_saldaconto && !is_fattura());
}
else
{
const bool corrisp = causale().corrispettivi();
bool clig, forg;
if (_iva == iva_acquisti)
{
forg = true;
clig = false;
}
else
{
forg = false;
clig = corrisp ? false : true;
}
m.show(-1, clig);
m.show(-2, forg);
if (corrisp) m.hide(F_STATOPAIV);
// Show/Hide campi valuta: F_VALUTAINTRA, F_CAMBIOINTRA, F_CORRISPETTIVO, F_CORRVAL (GROUP 4)
m.show(-4, causale().valintra());
m.show(F_DATAINTRA, causale().intra());
m.show(F_CODIVA, m.insert_mode()); // Codice IVA standard
TSheet_field& is = ivas();
is.enable_column(2, _iva == iva_acquisti); // Tipo detrazione
is.enable_column(4, !m.insert_mode()); // Tipo costo ricavo
if (is_fattura())
{
const TPartita* game = partite().first();
_scad_free = game == NULL || !game->esistono_abbuoni_diffcam(m.get_long(F_NUMREG));
if (m.edit_mode() && !_scad_free)
m.enable(DLG_DELREC, _scad_free); // Disabilita tasto elimina
m.enable(-1, _scad_free); // Disabilita cliente
m.enable(-2, _scad_free);
m.enable(F_ANNORIF, _scad_free); // Disabilita anno e numero partita
m.enable(F_NUMRIF, _scad_free);
m.enable(F_SOLAIVA, _scad_free); // Disabilita movimenti di sola IVA
m.enable(F_CODPAG, _scad_free); // Disabilita codice pagamento
m.enable(F_DESPAG, _scad_free); // Disabilita descrizione pagamento
m.enable(FS_RESET, _scad_free); // Disabilita tasto di reset
if (!_scad_free)
m.set(FS_RECALC, "", true); // Disabilita ricalcolo automatico
m.enable(FS_RECALC, _scad_free);
}
m.show(F_ADJUST_IVA, _quadratura);
}
// Show/Hide campi valuta: F_VALUTA, F_CAMBIO, F_DATACAMBIO (GROUP 3)
const bool valuta = _ges_val && is_saldaconto() && causale().valuta();
m.show(-3, valuta);
_sal_dirty = false; // Azzero il flag di modifica del saldaconto
fill_sheet(m); // Riempe righe contabili coi conti della causale
m.hide(F_LINKDOC);
}
void TPrimanota_application::init_query_mode(TMask& m)
{
enable_menu_item(M_FILE_PRINT);
enable_menu_item(M_FONT);
if (lnflag())
{
m.field(F_NUMREG).on_hit(); // Aggiorna opportunamente le date
}
else
{
m.set(F_DATAREG, _last_dreg);
}
_automatico->_step = 0; // Azzera flag di incasso immediato
TFilename tmp;
if (get_mask_swap_file(tmp))
{
TConfig ini(tmp, "23");
m.set(F_DATAREG, ini.get(MOV_DATAREG));
m.set(F_CODCAUS, ini.get(MOV_CODCAUS));
m.send_key(K_SPACE, DLG_NEWREC);
}
}
void TPrimanota_application::fill_sheet(TMask& m) const
{
const int filler = 16;
const int cgpos = m.id2pos(F_SHEETCG);
const int ivpos = m.id2pos(F_SHEETIVA);
if (cgpos > 0 && (ivpos > 0 || !is_saldaconto()))
{
TSheet_field& cgs = (TSheet_field&)m.fld(cgpos);
for (int r = cgs.items(); r < filler; r++)
cgs.row(r);
}
if (ivpos > 0)
{
TSheet_field& ivas = (TSheet_field&)m.fld(ivpos);
for (int r = ivas.items(); r < filler; r++)
ivas.row(r);
}
}
// Ritorna il prossimo numero di registrazione libero
// Certified 100%
bool TPrimanota_application::get_next_key(TToken_string& tmp)
{
tmp.add(F_NUMREG); tmp.add(_lastreg+1);
if (_rel->good()) // Not reinsert
{
TMask& m = curr_mask();
if (m.insert_mode())
{
tmp.add(F_CODCAUS); // Ricopia causale
switch (_automatico->_step)
{
case 1:
tmp.add(_automatico->_causale);
_msk[0]->set(F_CODCAUS, _automatico->_causale); // Joke get_mask
_iva = nessuna_iva; // Impedisce incremento del numero documento
break;
case 2:
tmp.add(_automatico->_causale_fattura);
_msk[0]->set(F_CODCAUS, _automatico->_causale_fattura); // Joke get_mask
_iva = _automatico->_iva_fattura; // Provoca incremento del numero documento
break;
default:
tmp.add(m.get(F_CODCAUS)); // Ultima causale usata
_msk[0]->set(F_CODCAUS, m.get(F_CODCAUS));
break;
}
tmp.add(F_DATAREG); // Ricopia data operazione
tmp.add(m.get(F_DATAREG));
tmp.add(F_DATACOMP); // Ricopia data competenza
if (m.field(F_DATACOMP).empty())
tmp.add(m.get(F_DATAREG));
else
tmp.add(m.get(F_DATACOMP));
if (_iva == iva_vendite)
{
tmp.add(F_DATADOC); tmp.add(m.get(F_DATADOC)); // Ricopia data documento
const long n = m.get_long(F_NUMDOC);
if (n > 0)
{ tmp.add(F_NUMDOC); tmp.add(n+1); } // incrementa numero documento
}
}
}
return true;
}
void TPrimanota_application::init_insert_mode(TMask& m)
{
init_mask(m);
m.first_focus(_firstfocus);
if (causale().reg().agenzia_viaggi())
m.set(F_DATA74TER, m.get(F_DATAREG));
if (iva() != nessuna_iva)
{
occas_mask().reset();
m.hide(F_OCCASEDIT);
m.hide(F_ADJUST_PRORATA); // In inserimento non puo' esistere un pro-rata errato!
if (causale().soloiva())
m.set(F_SOLAIVA, "X", true); // Propone movimento di sola iva
}
else
{
if (*causale().codice()) //
{
TString4 provv; provv << causale().provvisorio();
m.set(F_PROVVISORIO, provv, true); // Propone movimento di provvisorio
}
}
partite().destroy(); // Elimina tutte le partite in memoria
if (is_fattura())
{
activate_numrif(m, false);
const TString16 dt(m.get(F_DATADOC));
set_pagamento(NULL,dt);
set_scadenze(m);
}
else
{
set_pagamento(NULL,NULL); // Annulla gestione rate
}
_saldi.reset(); // Inizializza saldi
if (_automatico->_step == 1)
genera_automatico(_automatico->_tipo, NULL);
else
m.reset(F_DATACOMP); // Azzera quasi sempre la data di competenza
// La preservo solo per l'incasso immediato
_as400 = false; // Un movimento nuovo non puo' essere trasferito da AS400
TFilename tmp;
if (get_mask_swap_file(tmp))
{
TConfig ini(tmp, "23");
ini2mask(ini, m, false);
// Controllo se e' stato salvato il campo virtuale col codice IVA
if (m.id2pos(F_CODIVA) > 0)
{
const TString& codiva = ini.get("CODIVA", "23");
if (codiva.full())
m.set(F_CODIVA, codiva, 3);
}
// Devo ricalcolare il numero di protocollo nel caso di cambio causale al volo
if (m.id2pos(F_PROTIVA) > 0)
{
if (causale().iva() != nessuna_iva)
{
const long protiva = causale().reg().protocol() + 1;
m.set(F_PROTIVA, protiva, true); // Aggiorna protocollo IVA
}
else
m.reset(F_PROTIVA);
}
tmp.fremove();
}
}
void TPrimanota_application::init_modify_mode(TMask& m)
{
init_mask(m); // Inizializzazione standard
calcola_saldo(); // Verifica eventuali sbilanci contabili
TSheet_field& cg = cgs();
// Determina se il movimento e' stato trasferito da AS/400:
// praticamente controlla che non ci sia nessun tipo movimento sulle righe contabili.
_as400 = false;
if (is_saldaconto() || iva() != nessuna_iva)
{
if (cg.items() > 0)
{
_as400 = true;
for (int i = cg.items()-1; i >= 0 && _as400; i--)
{
const char rt = row_type(cg.row(i));
_as400 = rt <= ' ';
}
}
}
if (_as400 && is_pagamento())
{
m.set(SK_TIPORIGA, "A"); // Forza il tipo riga normale
m.disable(SK_TIPORIGA); // Disabilita la sua modifica
}
// Non controllare il prorata durante la cancellazione automatica
if (autodeleting() != 0x3)
{
if (!test_prorata()) // Controlla prorata
{
m.show(F_ADJUST_PRORATA);
m.set_handler(F_ADJUST_PRORATA, prorata_handler);
warning_box(TR("Questo movimento e' stato registrato con una percentuale\n"
"prorata non compatibile con quella corrente:\n"
"Premere il bottone di correzione automatica delle righe."));
}
else
{
// Nascondi il bottone del prorata se esiste
if (m.id2pos(F_ADJUST_PRORATA) >= 0)
{
m.set_handler(F_ADJUST_PRORATA, NULL);
m.hide(F_ADJUST_PRORATA);
}
}
}
const TRectype& mov = get_relation()->curr();
if (!mov.empty())
{
if (navigating())
{
TString msg;
if (mov.get_bool(MOV_STAMPATO))
msg << '\n' << TR("Il movimento e' gia' stato stampato sul libro giornale.");
if (mov.get_bool(MOV_REGST))
msg << '\n' << TR("Il movimento e' gia' stato stampato sul bollato.");
if (mov.get_bool(MOV_INVIATO))
msg << '\n' << TR("Il movimento e' stato inviato ad un'altra contabilita'.");
if (msg.not_empty())
{
msg.insert(TR("ATTENZIONE!"));
warning_box(msg);
}
}
// Abilito il bottone di collegamento ai documenti se possibile
const long numdoc = mov.get_long(MOV_DNDOC);
m.show(F_LINKDOC, numdoc > 0 && has_module(VEAUT));
}
}
// Controlla sulla causale se il segno del totale documento (ritsoc=false)
// o quello delle ritenute sociali (ritsoc=true) e' invertito rispetto al normale
bool TPrimanota_application::test_swap(bool ritsoc)
{
const char sez = ritsoc ? causale().sezione_ritsoc() : causale().sezione_clifo();
const bool s = (iva() == iva_vendite) ^ (sez == 'D');
return s;
}
int TPrimanota_application::read(TMask& m)
{
m.reset(); // Azzera campi e relativi dirty = 3
m.autoload(*_rel); // Carica testata
const long numreg = _rel->curr().get_long(MOV_NUMREG);
partite().destroy(); // Azzera tutte le partite
if (gestione_saldaconto() && causale().tipomov() != 0)
partite().add_numreg(numreg); // Carica le partite interessate
cgs().reset(); // Azzera tutte le righe contabili
if (iva() != nessuna_iva)
{
ivas().reset(); // Azzera tutte le righe iva
occas_mask().reset();
const TString16 occode(_rel->curr().get("OCFPI"));
occas_mask().set(O_CODICE, occode, true);
}
_saldi.reset(); // Azzera saldi
_saldi.set_movprovv(_rel->curr().get_char(MOV_PROVVIS) > ' ');
tiposal tsal = causale().apertura() ? apertura :
(causale().chiusura() ? chiusura : normale);
_saldi.set_tipo_saldo(tsal);
_saldi.set_anno_es(m.get_int(F_ANNOES));
_saldi.set_num_ulmov(numreg);
_saldi.set_data_ulmov((TDate)m.get(F_DATAREG));
_saldi.set_movimentato(true);
int i;
for (i = 0; i < _rel->cg_items(); i++)
{
const TRectype& r = _rel->cg(i);
TToken_string& riga = cgs().row(i); // Vuota la riga
TImporto import(r.get_char(RMV_SEZIONE), r.get_real(RMV_IMPORTO));
import.add_to(riga, 0); // Dare/Avere 101-102
TBill conto; conto.get(r);
riga.add(conto.string(0x3)); // Conto 103-107
_saldi.aggiorna(conto, import, false);
riga.add(""); // Codice descrizione 108
riga.add(r.get(RMV_DESCR)); // Descrizione riga 109
conto.get(r, true);
riga.add(conto.string(0x3)); // Contropartita 110-114
const char tipo = r.get_char(RMV_ROWTYPE);
riga.add(tipo, CG_ROWTYPE-FIRST_FIELD); // Tipo di riga 115
disable_cgs_cells(i, tipo);
}
if (_iva == nessuna_iva && is_fattura()) // Ci dovrebbero essere delle scadenze
{
pags().reset(); // Azzera sheet rate
if (!read_scadenze(m)) // Se non esiste fattura
{
const TString dd(m.get(F_DATADOC));
set_pagamento(NULL, dd); // Ignora codice pagamento in testata
}
}
if (_iva == nessuna_iva)
return _rel->status();
TMask_field& solaiva = m.field(F_SOLAIVA);
solaiva.set(i == 0 ? "X" : " ");
solaiva.on_key(K_TAB);
const int mese_liq = _rel->curr().get_int(MOV_MESELIQ);
if (mese_liq != 0)
{
const TDate data_reg = m.get_date(F_DATAREG);
const TDate data_liq(1, mese_liq, data_reg.year());
if (_rel->date2liq(data_reg) != _rel->date2liq(data_liq))
m.set(F_DIFFERITA, "X");
}
const bool to_swap = test_swap(false);
if (to_swap)
{
real totdoc(m.get(F_TOTALE));
totdoc = -totdoc;
m.set(F_TOTALE, totdoc);
}
for (i = 0; i < _rel->iva_items(); i++)
{
TRectype& r = _rel->iva(i);
TToken_string& riga = ivas().row(i);
real imponibile(r.get(RMI_IMPONIBILE));
if (to_swap) imponibile = -imponibile;
riga.add(imponibile.string()); // Imponibile 101
riga.add(r.get(RMI_CODIVA)); // IVA 102
riga.add(r.get(RMI_TIPODET)); // Detrazione 103
real imposta(r.get(RMI_IMPOSTA));
if (to_swap) imposta = -imposta;
if (imponibile.sign() * imposta.sign() < 0)
{
error_box(TR("Registrazione con imponibile e imposta con segni discordi:\n"
"assegnato il segno dell'imponibile"));
imposta = -imposta;
}
riga.add(imposta.string()); // Imposta 104
TBill c; c.get(r);
c.add_to(riga, 4, 0x7); // Conto 105-110
riga.add(r.get(RMI_NAVP));
}
calcola_imp(); // Calcola totale imponibile ed imposte
if (is_fattura()) // Ci dovrebbero essere delle scadenze
{
pags().reset(); // Azzera sheet rate
if (!read_scadenze(m)) // Se non esiste fattura
{
const TString& dd = m.get(F_DATADOC);
set_pagamento(NULL, dd); // Ignora codice pagamento in testata
}
}
return _rel->status();
}
// Trasferisce i dati da maschera a movimento di prima nota
void TPrimanota_application::mask2rel(const TMask& m)
{
m.autosave(*_rel);
TRectype& rec = _rel->curr(); // Record della testata
const long numreg = m.get_long(F_NUMREG);
const TDate datareg(m.get(F_DATAREG));
const int annoes = m.get_int(F_ANNOES);
_saldi.set_movprovv(m.get(F_PROVVISORIO)[0] > ' ');
tiposal tsal = causale().apertura() ? apertura :
(causale().chiusura() ? chiusura : normale);
_saldi.set_tipo_saldo(tsal);
_saldi.set_anno_es(annoes);
_saldi.set_num_ulmov(numreg);
_saldi.set_data_ulmov((TDate)m.get(F_DATAREG));
_saldi.set_movimentato(true);
const int tm = causale().tipomov();
char s[2];
if (tm > 0)
{
s[0] = tm+'0';
s[1] = '\0';
}
else
s[0] = '\0';
rec.put(MOV_TIPOMOV, s); // Tolto dalla maschera (su file e' alfanumerico)!
_rel->destroy_rows(numreg); // Destroy all records
cgs_pack(); // Destroy all null rows
// Controlla se e' un movimento con righe contabili
if (iva() == nessuna_iva || !m.get_bool(F_SOLAIVA))
{
TString_array& rows = cgs().rows_array();
for (int i = 0; i < rows.items(); i++)
{
TToken_string& row = rows.row(i);
TImporto n; n = row;
const TBill conto(row, 2, 0x3);
_saldi.aggiorna(conto, n, true);
TRectype &r = _rel->cg(i);
r.zero();
r.put(RMV_NUMREG, numreg); // Numero registrazione
r.put(RMV_ANNOES, annoes); // Anno esercizio
r.put(RMV_DATAREG, datareg); // Data di registrazione
r.put(RMV_NUMRIG, i+1); // Numero riga
r.put(RMV_SEZIONE, n.sezione()); // Sezione
r.put(RMV_IMPORTO, n.valore()); // Importo
conto.put(r); // Conto
row.get(); // Codice descrizione (ignorato)
const char* descr = row.get(); // Descrizione aggiuntiva
if (i > 0 || m.get(F_DESCR) != descr) // Salva la prima descrizione se diversa da testata
r.put(RMV_DESCR, descr); // Descrizione riga
r.put(RMV_TIPOCC, row.get()); // Contropartita
r.put(RMV_GRUPPOC, row.get());
r.put(RMV_CONTOC, row.get());
r.put(RMV_SOTTOCONTOC, row.get());
row.get(); // Descrizione contropartita
r.put(RMV_ROWTYPE, row.get(CG_ROWTYPE-FIRST_FIELD)); // Tipo riga
}
}
if (_iva == nessuna_iva) return;
// Calcola mese di liquidazione precedente
int mese_liq = 0;
if (m.get_bool(F_DIFFERITA))
{
TDate data_liq(m.get(F_DATAREG));
const int curr_liq = _rel->date2liq(data_liq);
data_liq.set_day(1); // Evita problemi coi mesi corti!
for (mese_liq = curr_liq-1; mese_liq > 0; mese_liq--)
{
data_liq.set_month(mese_liq);
if (_rel->date2liq(data_liq) != curr_liq)
break;
}
if (mese_liq <= 0)
mese_liq = 12;
}
rec.put(MOV_MESELIQ, mese_liq);
if (causale().corrispettivi())
{
rec.zero(MOV_TIPO);
rec.zero(MOV_CODCF); // Azzera il cliente nei movimenti dei corrispettivi
}
else
{
rec.put(MOV_TIPO, clifo());
if (m.field(F_OCCASEDIT).active()) // Se e' un occasionale
{
const TMask& om = occas_mask();
TRelation occas(LF_OCCAS);
om.autosave(occas); // Salva i dati anagrafici
int err = occas.write();
if (err == _isreinsert)
err = occas.rewrite();
if (err == NOERR)
rec.put(MOV_OCFPI, om.get(O_CODICE));
else
error_box(FR("Errore di scrittura sul file dei clienti/fornitori occasionali: %d"), err);
}
else
rec.zero(MOV_OCFPI);
}
const bool to_swap = test_swap(false);
if (to_swap)
{
real totale = rec.get_real(MOV_TOTDOC);
totale = -totale;
rec.put(MOV_TOTDOC, totale);
}
const bool intra = causale().intra();
ivas_pack();
TString_array& irows = ivas().rows_array();
for (int i = 0; i < irows.items(); i++)
{
TToken_string& row = irows.row(i);
TRectype &r = _rel->iva(i);
r.zero();
r.put(RMI_NUMREG, numreg);
r.put(RMI_NUMRIG, i+1);
r.put(RMI_ANNOES, annoes); // Anno d'esercizio della testata (che ca$$ata!)
r.put(RMI_INTRA, intra); // Causale intra (che ca$$ata!)
real imponibile(row.get(0));
if (to_swap) imponibile = -imponibile;
r.put(RMI_IMPONIBILE, imponibile);
r.put(RMI_CODIVA, row.get());
r.put(RMI_TIPODET, row.get());
real imposta(row.get());
if (to_swap) imposta = -imposta;
r.put(RMI_IMPOSTA, imposta);
r.put(RMI_TIPOCR, row.get());
// Roba obsoleta allo stato brado
const TBill c(row, 6);
const int rimp = bill2pos(c, 'I')+1;
r.put(RMI_RIGAIMP, rimp);
c.put(r);
r.put(RMI_NAVP, row.get(10));
}
}
void TPrimanota_application::check_saldi()
{
const int anno = _rel->curr().get_int(MOV_ANNOES);
TString_array& rows = cgs().rows_array();
FOR_EACH_ARRAY_ROW(rows, i, row)
{
TBill conto(*row, 2, 0x3);
conto.find();
const char sez = conto.sezione();
if (sez > ' ')
{
const TConto* c = _saldi.find(conto, anno);
if (c && !c->saldo_finale().is_zero() && c->saldo_finale().sezione() != sez)
warning_box(FR("Il conto della riga %i ha un saldo finale in %s, "
"contrariamente a quanto indicato sul piano dei conti"),
i+1, sez == 'A' ? TR("dare") : TR("avere"));
}
}
}
int TPrimanota_application::write(const TMask& m)
{
static int lasterr = NOERR;
const long numreg = m.get_long(F_NUMREG);
if (numreg > _lastreg) _lastreg = numreg; // Aggiorna ultima registrazione libera
if (lasterr == NOERR)
mask2rel(m); // Altrimenti raddoppia i saldi!
_last_dreg = m.get(F_DATAREG);
_last_dcom = m.get(F_DATACOMP);
const int err = _rel->write(true);
if (err == NOERR)
{
_saldi.registra();
check_saldi();
bool salvaconto = false;
const long old_nreg = NUMREG_PROVVISORIO;
if (iva() != nessuna_iva)
{
int tipauto = 0; // Tipo movimento automatico
TString4 causauto; // Possibile causale per incasso immediato
causale().reg().reread(); // Aggiorna protocollo IVA
if (is_saldaconto())
{
switch (causale().tipomov())
{
case tm_fattura:
write_scadenze(m); // Salva fattura
break;
case tm_nota_credito:
salvaconto = true; // Salva nota credito
break;
default:
break;
}
}
else
{
if (!m.get_bool(F_SOLAIVA) && !gestione_saldaconto())
{
causauto = causale().causale_inc_imm();
tipauto = causauto.full() ? 1 : 0;
}
}
if (iva() == iva_acquisti && tipauto <= 0)
{
// Genera regolarizzazione IVA acquisti
causauto = causale().causale_reg_iva();
tipauto = causauto.full() ? 2 : 0;
}
if (tipauto > 0 && causauto.full())
genera_automatico(tipauto, causauto);
}
else
{
if (is_fattura())
write_scadenze(m); // Salva fattura
salvaconto = is_pagamento();
}
if (salvaconto)
{
partite().update_reg(_rel->curr(), old_nreg);
partite().write();
}
link_m770();
link_cesp(m, "Insert");
link_intra(m, "Insert");
link_anal(m, "Insert");
}
lasterr = err;
return err;
}
int TPrimanota_application::rewrite(const TMask& m)
{
mask2rel(m);
const int err = _rel->rewrite(true);
if (err == NOERR)
{
_saldi.registra();
check_saldi();
if (is_saldaconto())
{
bool salvaconto = false;
if (iva() != nessuna_iva)
{
if (causale().tipomov() == tm_nota_credito)
salvaconto = true;
else
{
partite().update_reg(_rel->curr());
write_scadenze(m);
}
}
else
{
if (is_fattura())
write_scadenze(m); // Salva fattura
salvaconto = is_pagamento();
}
if (salvaconto)
{
partite().update_reg(_rel->curr());
partite().rewrite();
}
}
link_m770();
link_cesp(m, "Modify");
link_intra(m, "Modify");
link_anal(m, "Modify");
}
return err;
}
bool TPrimanota_application::remove()
{
const bool ok = TRelation_application::remove();
if (ok)
{
_saldi.registra();
check_saldi();
TMask& m = curr_mask();
if (is_saldaconto())
{
if (is_fattura())
{
m.reset(F_ANNORIF);
m.reset(F_NUMRIF);
write_scadenze(m);
}
else
{
notify_cgline_deletion(-1); // Notify deletion of all cg lines
partite().rewrite();
}
}
link_cesp(m, "Remove");
link_intra(m, "Remove");
link_anal(m, "Remove");
}
return ok;
}
///////////////////////////////////////////////////////////
// Gestione incasso immediato
///////////////////////////////////////////////////////////
void TPrimanota_application::genera_automatico(int tipo, const char* causimm)
{
const TCausale& caus = causale();
TMask& m = curr_mask();
if (causimm && *causimm) // Step 0
{
if (tipo > 0)
{
// Parte comune a tutti i movimenti automatici
_automatico->_tipo = tipo;
_automatico->_causale = causimm;
_automatico->_causale_fattura = m.get(F_CODCAUS);
_automatico->_iva_fattura = caus.iva();
_automatico->_datadoc = m.get(F_DATADOC);
_automatico->_numdoc = m.get(F_NUMDOC);
_automatico->_clifo.get(_rel->cg(0));
_automatico->_totale = m.get_real(F_TOTALE);
// Solo regolarizzazioni IVA
if (_automatico->_tipo == 2)
{
_automatico->_totale += m.get_real(F_RITFIS);
_automatico->_codiva = m.get(F_CODIVA);
if (_automatico->_codiva.blank() && _rel->iva_items() > 0)
_automatico->_codiva = _rel->iva(0).get(RMI_CODIVA);
}
_automatico->_step = 1;
}
}
else // Step 1
{
m.set(F_DATADOC, _automatico->_datadoc);
m.set(F_NUMDOC, _automatico->_numdoc);
switch (_automatico->_tipo)
{
case 1:
{ // Incasso Immediato
TBill contro; caus.bill(2, contro);
cgs().reset();
TToken_string& row1 = cgs().row(0);
TImporto imp(caus.sezione_clifo(), _automatico->_totale);
imp.add_to(row1, 0);
row1.add(_automatico->_clifo.string(0x3));
row1.add(" ");
row1.add(" ");
row1.add(contro.string(0x3));
TToken_string& row2 = cgs().row(1);
imp.swap_section();
imp.add_to(row2, 0);
row2.add(contro.string(0x3));
row2.add(" ");
row2.add(caus.desc_agg(2));
row2.add(_automatico->_clifo.string(0x3));
fill_sheet(m);
}
break;
case 2: // Regolarizzazione IVA
{
// Reperisce l'eventuale cliente associato al fornitore e lo propone
TString16 forn; forn.format("F|%ld", _automatico->_clifo.codclifo());
const TString& clnt = cache().get(LF_CLIFO, forn, CLI_CODCFASS);
m.set(F_CLIENTE, clnt);
m.set(F_TOTALE, _automatico->_totale); // Imposta il totale documento e ...
m.set(F_CODIVA, _automatico->_codiva, true); // ... scatena creazione prima riga IVA
}
break;
default:
break;
}
_automatico->_step = 2;
}
}
///////////////////////////////////////////////////////////
// Gestione collegamento 770
///////////////////////////////////////////////////////////
bool TPrimanota_application::is_percipient(long forn, char& tipper, long& codper) const
{
TString16 key; key.format("F|%ld", forn);
const TRectype& fornitore = cache().get(LF_CLIFO, key);
tipper = fornitore.get_char(CLI_TIPOAPER);
codper = fornitore.get_long(CLI_CODANAGPER);
return codper > 0;
}
long TPrimanota_application::calcola_m770(int tipo_coll, real& spese, real& compenso,
real& iva, real& ritfis)
{
const int m770 = causale().link_m770();
long forn = 0;
if (tipo_coll == 1)
{
TString_array& riva = ivas().rows_array();
TCodiceIVA codiva;
int i;
for (i = 0; i < riva.items(); i++)
{
TToken_string& row = riva.row(i);
codiva.read(row.get(1));
const TString& tipoiva = codiva.tipo();
const real imponibile(row.get(0));
if ((tipoiva == "ES" || tipoiva == "NI" ||tipoiva == "NS") && riva.items() > 1)
{
if (m770 != 5)
spese += imponibile;
else
compenso += imponibile; // MM000025
}
else
compenso += imponibile;
const real imposta(row.get(3));
iva += imposta;
}
i = type2pos('F');
if (i >= 0)
{
TImporto imp; imp = cgs().row(i);
ritfis = imp.valore();
}
i = type2pos('S');
if (i >= 0)
{
TImporto imp; imp = cgs().row(i);
ritfis += imp.valore();
}
}
if (tipo_coll == 3 || tipo_coll == 7)
{
TImporto imp;
TString_array& rcg = cgs().rows_array();
for (int i = 0; i < rcg.items(); i++)
{
TToken_string& row = rcg.row(i);
imp = row;
const char cf = row.get_char(2);
if (cf == 'F') // Evviva, e' un fornitore!
{
const long cod = row.get_long(5);
char tipper;
long codper;
if (!is_percipient(cod, tipper, codper))
continue; // Se non e' percipente ignoralo
if (forn == 0 && tipo_coll == 3)
{
forn = cod; // E' il primo che trovo!
}
else // Fine ricerca.
{
forn = 0;
compenso = ZERO;
break;
}
compenso = imp.valore();
}
}
}
if (tipo_coll == 4)
{
TBill zio; causale().bill(2, zio);
TString_array& rcg = cgs().rows_array();
for (int i = 0; i < rcg.items(); i++)
{
TToken_string& r = rcg.row(i);
const TBill bill(r, 3, 0x0);
if (zio == bill)
{
TImporto imp; imp = r;
ritfis = imp.valore();
break;
}
}
}
if (tipo_coll == 6)
{
TString_array& rcg = cgs().rows_array();
TToken_string& row = rcg.row(0);
TImporto imp;
imp = row;
if (imp.sezione() == 'D')
compenso = imp.valore();
else
compenso = ZERO;
}
return forn;
}
bool TPrimanota_application::link_m770()
{
const int m770 = causale().link_m770();
if (!has_module(M77AUT) || iva() == iva_vendite || m770 == 0)
return false;
int tipo_coll = 0;
char tipper = ' ';
long codper = 0;
real spese, compenso, imposte, ritenute;
if (iva() == iva_acquisti)
{
if (m770 == 1 || m770 == 5)
{
const long forn = curr_mask().get_long(F_FORNITORE);
if (is_percipient(forn, tipper, codper))
calcola_m770(tipo_coll = 1, spese, compenso, imposte, ritenute);
}
}
else // Movimento puramente contabile
switch (m770)
{
case 1:
{
tipo_coll = is_saldaconto() ? 7 : 3;
const long forn = calcola_m770(tipo_coll, spese, compenso, imposte, ritenute);
if (forn != 0)
is_percipient(forn, tipper, codper);
else
tipo_coll = 7;
}
break;
case 2:
calcola_m770(tipo_coll = 4, spese, compenso, imposte, ritenute);
break;
case 6:
calcola_m770(tipo_coll = 6, spese, compenso, imposte, ritenute);
break;
default:
break;
}
if (tipo_coll)
{
TToken_string s(80);
s.add(tipo_coll);
s.add(curr_mask().insert_mode() ? "I" : "M");
s.add(tipper);
s.add(codper);
s.add(curr_mask().get(F_NUMREG));
s.add(curr_mask().get(F_NUMDOC));
s.add(curr_mask().get(F_DATADOC));
if (iva() == iva_acquisti)
s.add(curr_mask().get(F_TOTALE));
else
s.add("");
s.add(spese.string());
s.add(compenso.string());
s.add(imposte.string());
s.add(ritenute.string());
const char* name = (tipo_coll == 4) ? "770 -1" : "770 -0";
TMessage m(name, "LINK770", s);
m.send();
TExternal_app a(name);
a.run();
}
return tipo_coll > 0;
}
HIDDEN void ini2bill(TConfig& ini, TBill& bil, bool contro)
{
const char tipo = ini.get_char(contro ? RMV_TIPOCC : RMV_TIPOC);
const int gruppo = ini.get_int(contro ? RMV_GRUPPOC : RMV_GRUPPO);
const int conto = ini.get_int(contro ? RMV_CONTOC : RMV_CONTO);
const long sottoconto = ini.get_long(contro ? RMV_SOTTOCONTOC : RMV_SOTTOCONTO);
bil.set(gruppo, conto, sottoconto, tipo);
}
HIDDEN bool set_not_empty(TMask& msk, int id, TConfig& ini, const char* var)
{
const TString& val = ini.get(var);
bool ok = val.full();
if (ok)
msk.set(id, val);
return ok;
}
HIDDEN bool add_not_empty(TToken_string& str, int pos, TConfig& ini, const char* var)
{
const TString& val = ini.get(var);
bool ok = val.full();
if (ok)
str.add(val, pos);
return ok;
}
void TPrimanota_application::ini2mask(TConfig& ini, TMask& msk, bool query)
{
TRelation_application::ini2mask(ini, msk, query);
if (query)
{
set_not_empty(msk, F_CODCAUS, ini, MOV_CODCAUS);
TString16 val = ini.get(MOV_DATAREG);
if (val.blank())
val = TDate(TODAY).string();
msk.set(F_DATAREG, val);
}
else
{
int i;
if (iva() != nessuna_iva)
{
add_cgs_tot(msk);
TSheet_field& is = ivas();
for (i = 0; ini.set_paragraph(format("%d,%d", LF_RMOVIVA, i+1)); i++)
{
TToken_string& riga = is.row(i);
iva_notify(is, i, K_SPACE);
add_not_empty(riga, 0, ini, RMI_IMPONIBILE); // Imponibile 101
add_not_empty(riga, 1, ini, RMI_CODIVA); // IVA 102
add_not_empty(riga, 2, ini, RMI_TIPODET); // Detrazione 103
add_not_empty(riga, 3, ini, RMI_IMPOSTA); // Imposta 104
TBill c; ini2bill(ini, c, false);
if (c.gruppo() > 0)
c.add_to(riga, 4, 0x7); // Conto 105-110
iva_notify(is, i, K_ENTER);
}
calcola_imp(); // Calcola totale imponibile ed imposte
}
TSheet_field& cg = cgs();
for (i = 0; ini.set_paragraph(format("%d,%d", LF_RMOV, i+1)); i++)
{
char tipo = ini.get_char(RMV_ROWTYPE);
if (tipo == '\0') tipo = ' ';
TBill conto; ini2bill(ini, conto, false);
int numrig = ini.get_int(RMV_NUMRIG)-1;
if (numrig != i) // Controllo se ho un numero riga valido
{
numrig = -1; // Normalmente aggiungi la riga in fondo
// Cerca una riga che abbia gia' il tipo ed il conto richiesto
if (strchr(" DINT", tipo) != NULL)
{
int nr = -1;
if (tipo == 'I' || tipo == ' ')
nr = bill2pos(conto, tipo);
else
nr = type2pos(tipo);
if (nr < 0)
tipo = ' ';
else
{
if (get_cgs_imp(nr).is_zero())
numrig = nr;
}
}
}
TToken_string& riga = cg.row(numrig);
if (numrig < 0 || !(cg.cell_disabled(numrig, 0) && cg.cell_disabled(numrig, 1)))
{
TImporto import(ini.get_char(RMV_SEZIONE), real(ini.get(RMV_IMPORTO)));
if (!import.is_zero())
import.add_to(riga, 0); // Dare/Avere 101-102
}
if (numrig < 0 || !cg.cell_disabled(numrig, 3))
{
if (conto.gruppo() > 0)
conto.add_to(riga, 2, 0x3); // Conto 103-107
}
riga.add("", 7); // Codice descrizione 108
add_not_empty(riga, 8, ini, RMV_DESCR); // Descrizione riga 109
ini2bill(ini, conto, true);
if (conto.gruppo() > 0)
conto.add_to(riga, 9, 0x3); // Contropartita 110-114
riga.add(tipo, cg.cid2index(CG_ROWTYPE)); // Tipo di riga 115
}
if (is_fattura())
{
TSheet_field& pag = pags();
const int start_items = pag.items();
msk.reset(FS_RECALC); // Disabilita ricalcolo automatico
for (i = 0; ini.set_paragraph(format("%d,%d", LF_SCADENZE, i+1)); i++)
{
TToken_string& row = pag.row(i);
if (i >= start_items)
pag_notify(pag, i, K_CTRL+K_INS);
pag_notify(pag, i, K_SPACE);
add_not_empty(row, 0, ini, SCAD_DATASCAD);
add_not_empty(row, 1, ini, SCAD_IMPORTO);
add_not_empty(row, 2, ini, SCAD_IMPORTOVAL);
pag_notify(pag, i, K_ENTER);
}
// In inserimento tento di riempire anche le scadenze
if (i == 0 && msk.insert_mode())
{
TString4 codpag = msk.get(F_CODPAG);
if (codpag.empty())
{
TToken_string key;
key = iva() == iva_acquisti ? "F" : "C";
key.add(ini.get(MOV_CODCF, "23"));
codpag = cache().get(LF_CLIFO, key, CLI_CODPAG);
}
if (codpag.full())
{
msk.set(FS_RECALC, "X"); // Forza ricalcolo automatico
msk.set(F_CODPAG, codpag);
set_scadenze(msk);
}
}
pagamento().set_sheet(pag);
}
}
}
bool TPrimanota_application::save(bool check_dirty)
{
if (_swap_mask == true)
{
_swap_mask = false;
return true;
}
return TRelation_application::save(check_dirty);
}
void TPrimanota_application::mask2ini(const TMask& msk, TConfig& ini)
{
TRelation_application::mask2ini(msk, ini);
int i, f;
for (i = 0; i < _rel->cg_items(); i++)
{
ini.set_paragraph(format("%d,%d", LF_RMOV, i+1));
const TRectype& rec = _rel->cg(i);
for (f = rec.items()-1; f >= 0; f--)
{
const char* name = rec.fieldname(f);
ini.set(name, rec.get(name));
}
}
for ( ; ini.set_paragraph(format("%d,%d", LF_RMOV, i+1)); i++)
ini.remove_all();
for (i = 0; i < _rel->iva_items(); i++)
{
ini.set_paragraph(format("%d,%d", LF_RMOVIVA, i+1));
const TRectype& rec = _rel->iva(i);
for (f = rec.items()-1; f >= 0; f--)
{
const char* name = rec.fieldname(f);
ini.set(name, rec.get(name));
}
}
for ( ; ini.set_paragraph(format("%d,%d", LF_RMOVIVA, i+1)); i++)
ini.remove_all();
if (is_fattura())
{
const long numreg = _rel->lfile().get_long(MOV_NUMREG);
TPartita* game = partite().first();
if (game)
{
const int rigafatt = game->prima_fattura(numreg);
if (rigafatt > 0)
{
const TRiga_partite& riga = game->riga(rigafatt);
for (int r = 1; r <= riga.rate(); r++)
{
ini.set_paragraph(format("%d,%d", LF_SCADENZE, r));
const TRectype& rec = riga.rata(r);
for (f = rec.items()-1; f >= 0; f--)
{
const char* name = rec.fieldname(i);
ini.set(name, rec.get(name));
}
}
for ( ; ; i++)
{
if (ini.set_paragraph(format("%d,%d", LF_SCADENZE, i+1)))
ini.remove_all();
else
break;
}
}
}
}
}
bool TPrimanota_application::link_cesp(const TMask& msk, const char* action)
{
// Controlla autorizzazione
if (!has_module(CEAUT))
return false;
// Controlla flag sulla causale
if (causale().link_cespiti() <= ' ')
return false;
// Controlla l'esistenza del programma cespiti
if (!fexist("ce1.exe"))
return false;
// Cerca una riga con tipo costo/ricavo 2,3,4
int i;
for (i = _rel->cg_items()-1; i >= 0; i--)
{
const TRectype& rec = _rel->cg(i);
const TBill zio(rec);
char tipo_cr = char('0' + zio.tipo_cr());
if (strchr("234", tipo_cr))
break;
}
if (i < 0)
return false;
TFilename cespini;
cespini.tempdir();
cespini.add("ActCsp.ini");
if (action && *action) // Dummy test
{
TConfig cespo(cespini, "Transaction");
cespo.set("Action", action);
mask2ini(msk, cespo);
}
TString appname;
appname << "ce1 -4 /c" << cespini;
TExternal_app app(appname);
bool ok = app.run() != 0;
return ok;
}
bool TPrimanota_application::link_intra(const TMask& m, const char* action)
{
// Controlla autorizzazione
if (!has_module(INAUT))
return false;
// Controlla flag sulla causale
if (!causale().intra())
return false;
// Controlla l'esistenza del programma intra
if (!fexist("in0.exe"))
return false;
const bool bModify = xvt_str_compare_ignoring_case(action, "Modify") == 0;
TFilename intrini;
intrini.tempdir();
intrini.add("ActIntra.ini");
TString appname;
TConfig intro(intrini, "Transaction");
bool call_rettifiche = false;
const TDate datareg = m.get(F_DATAREG);
const TDate dataint = m.get(F_DATAINTRA);
if (dataint < datareg)
{
const TIntra_frequency freq;
const char tipo = iva() == iva_acquisti ? 'A' : 'C';
call_rettifiche = freq.compare_periodo(dataint, datareg, tipo) < 0;
}
if (call_rettifiche)
{
const TIntra_frequency freq;
const char tipo = iva() == iva_acquisti ? 'B' : 'D';
TRelation rel(LF_RIEPRETT);
TRectype& curr = rel.curr();
curr.put("TIPO", tipo);
curr.put("ANNO", datareg.year());
curr.put("PERIODO", freq.date2periodo(datareg, tipo));
TCursor cur(&rel, "", 1, &curr, &curr);
const TRecnotype items = cur.items();
cur.freeze();
long last_rett = 0;
for (cur = 0; cur.pos() < items; ++cur)
{
const long n = curr.get_long("NUMRIG");
if (n > last_rett)
last_rett = n;
if (curr.get_long("NUMREG") == m.get_long(F_NUMREG))
return curr.edit(0, NULL, "in0 -6");
}
intro.set("Action", "Insert");
TString4 str; str.format("%d", LF_RIEPRETT);
intro.set_paragraph(str);
intro.set("TIPO", tipo == 'B' ? "B" : "D");
intro.set("ANNO", datareg.year());
intro.set("PERIODO", freq.date2periodo(datareg, tipo));
intro.set("NUMRIG", last_rett+1);
intro.set("ANNORETT", dataint.year());
intro.set("PERETT", freq.date2periodo(dataint, tipo));
intro.set("STATO", m.get(F_STATOPAIV));
intro.set("PIVA", tipo == 'B' ? m.get(F_PIVAFORNITORE) : m.get(F_PIVACLIENTE));
intro.set("NUMREG", m.get(F_NUMREG));
appname << "in0 -6 /i" << intrini;
}
else
{
if (bModify)
{
TString16 key;
key << m.get(F_NUMREG);
const TRectype & intra = cache().get(LF_INTRA, key);
if (intra.empty())
action = "Insert";
}
intro.set("Action", action);
TString str; // Stringa jolly di lavoro
str.format("%d", LF_INTRA);
intro.set_paragraph(str);
intro.set("NUMREG", m.get(F_NUMREG));
intro.set("DATAREG", m.get(F_DATAREG));
if (m.field(F_CLIENTE).shown())
{
intro.set("TIPOMOV", "C");
intro.set("TIPOCF", "C");
intro.set("CODCF", m.get(F_CLIENTE));
}
else
{
intro.set("TIPOMOV", "A");
intro.set("TIPOCF", "F");
intro.set("CODCF", m.get(F_FORNITORE));
}
// Controlla flag sulla causale
const bool valintra = causale().valintra();
if (valintra)
{
intro.set("CODVAL", m.get(F_VALUTAINTRA));
intro.set("CAMBIO", m.get(F_CAMBIOINTRA));
}
// Inserisci il totale documento solo in inserimento!
if (xvt_str_compare_ignoring_case(action, "Insert") == 0)
{
real totdoc = m.get_real(valintra ? F_CORRISPETTIVO : F_IMPONIBILI);
if (test_swap(false))
totdoc = -totdoc;
intro.set("TOTDOC", totdoc.string());
}
else
intro.remove("TOTDOC"); // Evita di cambiare il valore preesistente
appname << "in0 -4 /i" << intrini;
}
bool ok = false;
if (!appname.empty())
{
intro.set_paragraph(""); // Flush pending writes
TExternal_app app(appname);
ok = app.run() == 0;
}
::remove(intrini);
return ok;
}
bool TPrimanota_application::link_anal(const TMask& msk, const char* action)
{
// Controlla autorizzazione
if (!(has_module(CMAUT) || has_module(CAAUT)))
return false;
// Controlla flag sulla causale
if (!causale().link_analitica())
return false;
// Controlla l'esistenza del programma dei movimenti analitici
if (!fexist("ca2.exe"))
return false;
TConfig cfg(CONFIG_DITTA, "ca");
const TDate data_att = cfg.get("DtAttCa");
if (data_att.ok())
{
const TDate data_cmp = msk.get(F_DATACOMP);
if (data_cmp < data_att) // La data di competenza precede la data di attivazione analitica
return false;
}
// Cerco se c'e' almeno un conto interessato all'analitica
bool bAnalBill = false;
TSheet_field& sheet = msk.sfield(F_SHEETCG);
FOR_EACH_SHEET_ROW(sheet, i, row)
{
const TBill bill(*row, 3, 0x0);
bAnalBill = bill.is_analitico();
if (bAnalBill)
break;
}
long nExist = 0L;
if (action[0] == 'I')
{
// Se non ci sono conti analitici e' inutile inserire
if (!bAnalBill)
return false;
}
else
{
// Se sono in modo Modify o Remove, controllo se esiste il movimento
TLocalisamfile movana(LF_MOVANA);
movana.setkey(3);
movana.put(MOVANA_NUMREGCG, msk.get(F_NUMREG));
if (movana.read() == NOERR)
nExist = movana.get_long(MOVANA_NUMREG);
if (!nExist)
{
if (action[0] == 'R') // Nulla da cancellare
return false;
if (!bAnalBill) // Non c'erano e non ci sono tuttora conti analitici
return false;
action = "Insert"; // Il movimento e' andato perduto!
}
}
TFilename ini; ini.tempdir();
ini.add("ActAnal.ini");
ini.fremove(); // Azzera l'eventuale copia precedente
// Parentesi strategiche per salvare il config
{
TConfig config(ini, "Transaction");
config.set("Action", action);
TString4 para; para << LF_MOVANA;
config.set_paragraph(para);
config.remove_all();
config.set(MOVANA_NUMREG, nExist);
config.set(MOVANA_NUMREGCG, msk.get(F_NUMREG));
}
TString cmd; cmd << "ca2 -0 /i" << ini;
TExternal_app app(cmd);
app.run();
return true;
}
bool TPrimanota_application::protected_record(TRectype& mov)
{
bool ok = !TRelation_application::protected_record(mov);
if (ok && autodeleting() == 0x3)
{
static long last_checked_numreg = 0L;
const long numreg = mov.get_long(MOV_NUMREG);
if (last_checked_numreg != numreg)
{
if (mov.get_bool(MOV_STAMPATO))
{
ok = yesno_box(FR("Il movimento %ld e' gia' stato stampato sul libro giornale:\n"
"si desidera eliminarlo ugualmente?"), numreg);
}
if (ok && mov.get_bool(MOV_REGST))
{
ok = yesno_box(FR("Il movimento %ld e' gia' stato stampato sul bollato:\n"
"si desidera eliminarlo ugualmente?"), numreg);
}
if (ok && mov.get_bool(MOV_INVIATO))
{
ok = yesno_box(FR("Il movimento %ld e' stato inviato ad un'altra contabilita':\n"
"si desidera eliminarlo ugualmente?"), numreg);
}
if (ok)
last_checked_numreg = numreg;
}
}
return !ok;
}
int cg2100 (int argc, char** argv)
{
TPrimanota_application* a = new TPrimanota_application;
a->run(argc, argv, TR("Prima nota"));
delete a;
return 0;
}