campo-sirio/cg/cg2100.cpp

2176 lines
62 KiB
C++
Raw Normal View History

#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);
Patch level : 2.0 604 Files correlati : cg0.exe cg0500a.msk cg2.exe cg2100s.msk Ricompilazione Demo : [ ] Commento : CM20044 Causale senza tipo documento e con tipo movimento fattura. Mi propone la pagina delle scandenze completamente vuota pur avendo indicato il codice pagamento in testata. La seguente pagina riconosce il pagamento solo se clicco sul botone di reset. CM20045 Causale senza tipo documento e con tipo movimento nota di credito. Mi lascia registrare in prima nota senza portarmi nella gestione partite per chiudere le eventuali fatture.Come faccio ? ATTENZIONE: eliminata possibilita' di creare note di credito senza tipo documento CM20046 Causale senza tipo documento e con tipo movimento fattura o nota di credito. In prima nota non viene mai controllato il totale della testata presente nel campo "Voci per saldaconto" con quanto viene indicato poi nelle righe. CM20047 Causale senza tipo documento e con tipo movimento fattura/nota di credito. Se inserisco una registrazione con tipo movimento nota credito e passo successivamente ad una registrazione con causale con tipo movimento fattura, pur mettendo il codice di pagamento, la procedura non propone la pagina delle scadenze.Questo non accade se esco dalla prima nota dopo la registrazione della nota credito e rientro per registrare la fattura. CM20048 Inserisco un pagamento a fronte di un movimento nato da causale senza tipo documento e tipo movimento fattura. Se in testa indico il numero e la data del documento va tutto bene fino a che non seleziono la rata che intendo pagare, ma quando do conferma nella finestra del pagamento, la procedura mi riporta nella maschera della prima nota senza passare da quella delle partite. Solo cliccando di nuovo su conferma, la procedura mi apre la maschera delle partite. Se non indico i riferimenti del documento sulla testata della registrazione, va tutto bene. git-svn-id: svn://10.65.10.50/trunk@11508 c028cbd2-c16b-5b4b-a496-9718f37d4682
2003-10-17 08:28:05 +00:00
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(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));
}
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;
}