campo-sirio/ef/ef0300.cpp
guy 6fa29e77d4 Migliorata risoluzione conflitti persone F/G su distinte
git-svn-id: svn://10.65.10.50/branches/R_10_00@23086 c028cbd2-c16b-5b4b-a496-9718f37d4682
2015-05-15 08:43:54 +00:00

1004 lines
33 KiB
C++
Executable File
Raw Blame History

#include <msksheet.h>
#include <relapp.h>
#include "ef0.h"
#include "ef0300.h"
#include "ef0301.h"
#include <clifo.h>
//////////////////////////////////////////////////////////////////////////////
// Classe per la gestione di distinte (inserimento, modifica, cancellazione)//
// e per la creazione automatica di distinte per importi. //
//////////////////////////////////////////////////////////////////////////////
class TVariazione_distinte: public TRelation_application
{
TMask *_msk, *_m2;
TDistinta *_distinta;
TRelation *_rel;
protected:
virtual void init_query_mode(TMask&);
virtual void init_insert_mode(TMask&);
virtual void init_modify_mode(TMask&);
virtual bool get_next_key(TToken_string& key);
virtual int read(TMask& m);
virtual int rewrite(const TMask& m);
virtual int write(const TMask& m);
virtual bool remove();
virtual bool has_filtered_cursor() const { return true; }
virtual bool changing_mask(int mode) { return false; }
virtual TMask* get_mask(int mode) { return _msk; }
static bool tipodist_handler(TMask_field& f, KEY k);
static bool importo_handler(TMask_field& f, KEY k);
static bool imp_sel_handler(TMask_field& f, KEY k);
static bool check_handler(TMask_field& f, KEY k);
static bool imp_notify(TSheet_field& s, int r, KEY key);
static bool dist_check_handler(TMask_field& f, KEY key);
static bool impdist_notify(TSheet_field& s, int r, KEY key);
static bool impdist_handler(TMask_field& s, KEY key);
static bool conferma_handler(TMask_field& f, KEY k);
static bool annulla_handler(TMask_field& f, KEY k);
static bool data_handler(TMask_field& f, KEY k);
static bool ordina_handler(TMask_field& f, KEY k);
static bool uncontabilize_handler(TMask_field& f, KEY k);
static void calcola_totale();
static void calcola();
static void aggiungi();
static bool effetto_aggiunto(const long numero);
static void carica_riba(int tipopag, const bool reset = true);
static void ordina(COMPARE_FUNCTION cf);
static const TString& get_ban_desc(const TRectype& eff);
// ritorna un riferimento allo sheet degli effetti (righe) nella
// distinta
TSheet_field& righe_sheet() const { return _msk->sfield(F_SHEET_RIBA); }
// ritorna un riferimento allo sheet delle righe
TSheet_field& righe_sel_sheet() const { return _m2->sfield(F_SHEET); }
bool cerca(long num);
bool user_create();
bool user_destroy();
void aggiorna();
TToken_string* common_f(const TMask& m, TToken_string& datidist);
public:
virtual TRelation* get_relation() const { return _rel;}
};
// restituisce un riferimento all' applicazione
inline TVariazione_distinte& app(){ return (TVariazione_distinte&)main_app(); }
// quando si va in query mode abilita i campi relativi alla chiave
// di ricerca e resetta i campi relativi ai totali
void TVariazione_distinte::init_query_mode(TMask&)
{
_msk->enable(F_NUMBER);
_msk->enable(F_TIPODIST);
_msk->reset(F_TOTIMP);
_msk->enable(F_TIPOPAG);
_msk->enable(F_TIPOCF);
_msk->hide(F_UNCONTABIL);
}
// quando si va in insert mode resetta i campi della maschera relativi
// ai totali, abilita i campi relativi alla valuta e disabilta i campi
// relativi alla chiave di ricerca
void TVariazione_distinte::init_insert_mode(TMask& m)
{
m.reset(F_TOTIMP);
m.enable(F_CODVAL);
m.disable(F_NUMBER);
m.disable(F_TIPODIST);
m.enable(F_TIPOPAG);
m.enable(F_TIPOCF);
}
// quando si va in modify mode disabilta i campi relativi alla chiave
// di ricerca
void TVariazione_distinte::init_modify_mode(TMask& m)
{
m.disable(F_NUMBER);
m.disable(F_TIPODIST);
m.disable(F_TIPOPAG);
m.disable(F_TIPOCF);
const bool cont = _distinta->contabilizzata();
m.show(F_UNCONTABIL, cont);
}
// ritorna il prossimo numero di distinta valido
bool TVariazione_distinte::get_next_key(TToken_string& key)
{
const TString& tipodist = curr_mask().get(F_TIPODIST);
TLocalisamfile& effetti = _rel->lfile();
effetti.put(EFF_TIPODIST,tipodist);
effetti.put(EFF_NDIST,99999L);
effetti.setkey(4);
long ndist = 1;
const int err = effetti.read(_isgreat);
if (err != _isemptyfile)
{
if (err == NOERR)
effetti.prev();
if (effetti.get(EFF_TIPODIST) == tipodist)
ndist += effetti.get_long(EFF_NDIST);
}
key.format("%d|%ld",F_NUMBER,ndist);
return true;
}
// ritorna true se trovo nell'array delle righe distinta l'effetto
// passato
bool TVariazione_distinte::cerca(long num)
{
TArray& righedist = _distinta->righe();
for (int i = _distinta->items() - 1; i >= 0; i--)// ciclo sugli elementi dell'array
{
TEffetto& eff = (TEffetto&)righedist[i];
if (num == eff.get_long(EFF_NPROGTR))
return true;
}
return false;
}
// metodo che permette di scivere sull'array (in memoria) gli
// effetti presenti nello sheet
void TVariazione_distinte::aggiorna()
{
TSheet_field& shrighe = righe_sheet();
int items = shrighe.items();
for (int i = 0; i < items; i++)// prendo tutte le righe dello sheet
{
TToken_string& row = shrighe.row(i);
row.restart();
long num = row.get_long(shrighe.cid2index(F_NRIBA));
if (!cerca(num))// se non <20> gi<67> presente in memoria
{ // carico l'effetto nell'array
const TRectype & rec = cache().get(LF_EFFETTI, num);
TEffetto* effetto = new TEffetto((TRectype &) rec);
TArray& righedist = _distinta->righe();
righedist.add(effetto);
}
}
}
// Metodo che permette di prendere i dati dalla maschera e metterli in
// una TToken_string che servir<69> per passarli alla write della distinta
TToken_string* TVariazione_distinte::common_f(const TMask& m, TToken_string& datidist)
{
const char tipodist = m.get(F_TIPODIST)[0]; // prendo i dati
const long ndist = m.get_long(F_NUMBER); // identificatvi della
const TDate datadist = (TDate)m.get(F_DATA); // distinta
const TString& codabi = m.get(F_CODABIP); // dalla maschera
const TString& codcab = m.get(F_CODCABP);
TString4 progbnp = m.get(F_PROG);
if (real::is_null(progbnp))
progbnp.cut(0);
else
progbnp.right_just(2, '0');
m.autosave(*_rel);
datidist.add(tipodist); // inserisco i dati nella
datidist.add(ndist); // token string
datidist.add(datadist);
datidist.add(codabi);
datidist.add(codcab);
datidist.add(progbnp);
return &datidist;
}
const TString& TVariazione_distinte::get_ban_desc(const TRectype& eff)
{
TString16 codice = eff.get(EFF_CODABI);
const TString& des_abi = cache().get("%BAN", codice, "S0");
codice << eff.get(EFF_CODCAB);
const TString& des_cab = cache().get("%BAN", codice, "S0");
if (des_cab.starts_with(des_abi))
return des_cab;
TString& tmp = get_tmp_string();
tmp << des_abi << ' ' << des_cab;
tmp.strip_double_spaces();
return tmp.cut(50);
}
// carica nella maschera i dati dai files
int TVariazione_distinte::read(TMask& m)
{
m.autoload(*_rel);
int err = _rel->status();
if (err == NOERR)
{
//resetto l'array che contiene gli effetti nella distinta
_distinta->reset();
// legge la distinta dal record corrente della relazione
err = _distinta->read(_rel->curr());
if (err == NOERR)
{
TToken_string riga(80);
TSheet_field& shrighe = righe_sheet();
shrighe.reset();
// prendo il numero di effetti nella distinta
const int items = _distinta->items();
// carico tutti gli effetti della distinta nello sheet
if (items > 0)
{
TString16 codice; // Codice per cache
TArray& righedist = _distinta->righe();
TEffetto& e = (TEffetto&)righedist[0];
m.set(F_DATA, e.get(EFF_DATADIST));// distinta
m.set(F_CODABIP, e.get(EFF_CODABIP)); // dalla maschera
m.set(F_CODCABP, e.get(EFF_CODCABP));
m.set(F_PROG, e.get(EFF_PROGBNP));
for (int i = 0; i < items; i++)
{
TEffetto& eff = (TEffetto&)righedist[i];
riga.cut(0);
riga.add(' ');
const long numero = eff.get_long(EFF_NPROGTR);
riga.add(numero);
riga.add(eff.get(EFF_DATASCAD));
//prendo la ragione sociale del cliente conoscendone il codice
codice.cut(0);
codice << eff.get_tipo(); codice << '|' << eff.get(EFF_CODCF);
riga.add(cache().get(LF_CLIFO, codice, CLI_RAGSOC));
riga.add(get_ban_desc(eff));
if (eff.fatt())// se l'effetto contiene solo una fattura
{ // metto i riferimenti al documento ed al numero di rata
const TRectype& rec_r = eff.row_r(1);
riga.add(rec_r.get(REFF_NFATT));
riga.add(rec_r.get(REFF_DATAFATT));
if (eff.rows_r() == 1)
riga.add(rec_r.get(REFF_NRATA));
else
riga.add(TR("Varie"));
}
else// se l'effetto contiene pi<70> di una fattura
{ // non metto i riferimenti al documento ed al numero di rata
riga.add(TR("Varie"));
riga.add(TR("Varie"));
riga.add(TR("Varie"));
}
//gestisco il controllo sulla presenza o meno di una valuta
const TString4 codval(eff.get(EFF_CODVAL));
if (i == 0)
{
const bool valuta = ::is_true_value(codval);
m.set(F_CODVAL, codval);
m.enable(F_CODVAL, valuta);
}
riga.add(codval);
const real soldi = eff.get_real(EFF_IMPORTO);
riga.add(soldi.string());
const real soldival = eff.get_real(EFF_IMPORTOVAL);
if (!soldival.is_zero())
riga.add(soldival.string());
shrighe.row(i) = riga;
}
}
}
}
return err;
}
// riscrive distinta
int TVariazione_distinte::rewrite(const TMask& m)
{
// prima di riscrive controllo se ci sono effetti nello sheet
// selezionati per l'eliminazione
TEffetto eff;
TLocalisamfile file(LF_EFFETTI);
const char tipodist = _msk->get(F_TIPODIST)[0];
const long ndist = _msk->get_long(F_NUMBER);
TDistinta * distinta = app()._distinta;
TSheet_field& sf = righe_sheet();
int items = sf.items();
int to_delete = 0;
for (int i = items - 1; i >= 0 ; i--)
{
TToken_string& row = sf.row(i);
if (*row.get(0) == 'X') // to delete
to_delete++;
}
if (items <= to_delete)
{ // non posso cancellare tutti gli effetti di una distinta
error_box(TR("Impossibile escludere tutti gli effetti dalla distinta.\nUtilizzare elimina per cancellarla."));
return NOERR;
}
if (to_delete > 0)
{
TArray& righedist = distinta->righe();
//ciclo sugli elementi dello sheet
for (int i = items - 1; i >= 0; i--)
{
TToken_string& row = sf.row(i);
if (*row.get(0) == 'X') // to delete
{
const long num = row.get_long(1);
//ciclo sugli elementi dell'array
for (int j = 0; j < distinta->items(); j++)
{
TEffetto& eff = (TEffetto&)righedist[j];
if (num == eff.get_long(EFF_NPROGTR))
{
// tolgo l'effetto dall'array
righedist.destroy(j,true);
break;
}
}
// tolgo l'effetto dallo sheet
sf.destroy(i);
eff.read(file, tipodist, ndist, i + 1);
eff.zero(EFF_TIPODIST);
eff.zero(EFF_NDIST);
eff.zero(EFF_DATADIST);
eff.zero(EFF_NRIGADIST);
eff.zero(EFF_CODABIP);
eff.zero(EFF_CODCABP);
eff.zero(EFF_PROGBNP);
eff.rewrite(file);
}
}
}
//resetto l'array che contiene gli effetti nella distinta
int err = _distinta->reset();
aggiorna();
TToken_string datidist;
err = _distinta->rewrite(common_f(m, datidist));
if (err == NOERR)
{ // riposiziono la relazione
_rel->lfile().setkey(4);
TRectype& curr = _rel->curr();
curr.put(EFF_TIPODIST, tipodist);
curr. put(EFF_NDIST, ndist);
curr. put(EFF_NRIGADIST, 1);
_rel->read();
}
return err;
}
// scrive distinta
int TVariazione_distinte::write(const TMask& m)
{
//resetto l'array che contiene gli effetti nella distinta
int err = _distinta->reset();
char tipodist = m.get(F_TIPODIST)[0];
long ndist = m.get_long(F_NUMBER);
aggiorna();
TToken_string datidist;
err = _distinta->write(true, common_f(m, datidist));
if (err == NOERR)
{ //riposiziono la relazione
_rel->lfile().setkey(4);
TRectype& curr = _rel->curr();
curr.put(EFF_TIPODIST, tipodist);
curr. put(EFF_NDIST, ndist);
curr. put(EFF_NRIGADIST, 1);
_rel->read();
}
return err;
}
// Metodo che permette di eliminare una distinta, l'eliminazione
// consiste nell'andare a togliere dagli effetti i dati ad essa
// relativi.
bool TVariazione_distinte::remove()
{
TMask& m = *_msk;
char tipodist = m.get(F_TIPODIST)[0];
long ndist = m.get_long(F_NUMBER);
return _distinta->remove(tipodist, ndist) == NOERR;
}
// creo la relap
bool TVariazione_distinte::user_create()
{
open_files(LF_TAB, LF_TABCOM, LF_CLIFO, LF_EFFETTI, LF_REFFETTI, LF_CESS, NULL);
_msk = new TMask("ef0300a");
_m2 = new TMask("ef0300c");
_rel = new TRelation(LF_EFFETTI);
if (_rel->last() == NOERR)
_msk->set(F_TIPODIST, _rel->curr().get(EFF_TIPODIST));
_distinta = new TDistinta;
set_search_field(F_NUMBER);//setto il campo di ricerca della distinta
_msk->set_handler(F_TIPODIST, tipodist_handler);
_msk->set_handler(F_IMPBUTTON, importo_handler);
_msk->set_handler(F_UNCONTABIL, uncontabilize_handler);
TSheet_field& rs = righe_sheet();
rs.set_notify(impdist_notify);
rs.set_handler(impdist_handler);
rs.sheet_mask().set_handler(FIRST_FIELD, dist_check_handler);
_m2->set_handler(F_IMPSEL, imp_sel_handler);
_m2->set_handler(DLG_OK, conferma_handler);
_m2->set_handler(DLG_CANCEL, annulla_handler);
_m2->set_handler(F_DADATA, data_handler);
_m2->set_handler(F_ADATA, data_handler);
_m2->set_handler(F_TIPORD, ordina_handler);
TSheet_field& rss = righe_sel_sheet();
rss.set_notify(imp_notify);
rss.sheet_mask().set_handler(FIRST_FIELD, check_handler);
return true;
}
// distruggo la relap
bool TVariazione_distinte::user_destroy()
{
delete _msk;
delete _m2;
delete _rel;
delete _distinta;
return true;
}
// Cerca se la riba indicata da <numero> e' gia stato inserita nello spreadsheet principale
bool TVariazione_distinte::effetto_aggiunto(const long numero)
{
TMask* m = app()._msk;
TSheet_field& sf_riba = (TSheet_field&)m->field(F_SHEET_RIBA);
bool rt = false;
const int items = sf_riba.items();
for (int i=0; i<items && !rt; i++)
{
TToken_string& row = sf_riba.row(i);
if (row.get_long(1) == numero)
rt = true;
}
return rt;
}
// Permette di caricare lo sheet per la selezione delle riba da
// aggiungere alla distinta: vengono presi tutti gli effetti sul file
// LF_EFFETTI che non hanno ancora un riferimento ad una distinta;
// inoltre <20> possibile inserire nella distinta effetti aventi lo stesso
// tipo di pagamento.
void TVariazione_distinte::carica_riba(int tipopag, const bool reset)
{
TWait_cursor hourglass;
// deve caricare solo quegli effetti che non hanno riferimento alla
// distinta quindi setta i campi ad essa relativi a zero
char tipodist = 0;
long ndist = 0;
int nrigadist = 0;
TEffetto eff;
TLocalisamfile f(LF_EFFETTI);
// per prendere la ragione sociale del cliente di cui ho il codice
TToken_string riga(80);
TMask& m2 = *app()._m2;
if (reset)
m2.reset();
TSheet_field& sf = m2.sfield(F_SHEET);
if (reset)
sf.reset();
TString4 codval = app()._msk->get(F_CODVAL);
TString16 codtab;
int err, i = 0;
err = eff.read(f, tipodist, ndist, nrigadist);
int tipop = eff.get_int(EFF_TIPOPAG);
const char tipo_cf = app()._msk->get(F_TIPOCF)[0]; // 'C'liente o 'F'ornitore
char tipo_a = ' '; // 'F'isica o 'G'iuridica
while ( (err == NOERR) && (tipodist == 0))
{
// se effetti di tipo cambiario (pagher<65>, tratta, tratta accettata)
// se non indico un tipo di effetto prendo il tipo del primo che
// seleziono
const bool to_select = (tipopag == 0) || (tipopag == tipop) ||
((tipopag == 2 || tipopag == 5 || tipopag == 7) &&
(tipop == 2 || tipop == 5 || tipop == 7));
const char tipo = eff.get_tipo(); // C o F
const TString4 valuta = eff.get(EFF_CODVAL);
const bool valuta_ok = ::same_values(valuta, codval);
const long numero = eff.get_long(EFF_NPROGTR);
const bool is_good = to_select && valuta_ok && !effetto_aggiunto(numero) && tipo == tipo_cf;
if (is_good)
{
riga = " "; // Campo selezione
riga.add(numero);
riga.add(eff.get(EFF_DATASCAD));
TString16 codice;
codice << tipo << '|' << eff.get(EFF_CODCF);
riga.add(cache().get(LF_CLIFO, codice, CLI_RAGSOC));
riga.add(get_ban_desc(eff));
if (eff.fatt())// se l'effetto contiene solo una fattura
{ // metto i riferimenti al documento ed al numero di rata
const TRectype& rec_r = eff.row_r(1);
riga.add(rec_r.get(REFF_NFATT));
riga.add(rec_r.get(REFF_DATAFATT));
if (eff.rows_r() == 1)
riga.add(rec_r.get(REFF_NRATA));
else
riga.add((TR("Varie")));
}
else// se l'effetto contiene pi<70> di una fattura
{ // non metto i riferimenti al documento ed al numero di rata
riga.add((TR("Varie")));
riga.add((TR("Varie")));
riga.add((TR("Varie")));
}
riga.add(valuta);
const real soldi = eff.get_real(EFF_IMPORTO);
riga.add(soldi.string());
const real soldival = eff.get_real(EFF_IMPORTOVAL);
if (!soldival.is_zero())
riga.add(soldival.string());
sf.row(i++) = riga;
}
f.setkey(4);
err = eff.next(f);//leggo l'effetto successivo
tipodist = eff.get(EFF_TIPODIST)[0];// e ne prendo il tipo distinta
tipop = eff.get_int(EFF_TIPOPAG);
}
}
// Handler per gestire il fatto che una distinta allo sconto pu<70>
// contenere solo effetti cambiari
bool TVariazione_distinte::tipodist_handler(TMask_field& f, KEY k)
{
if (k == K_SPACE)
{
TMask& m = f.mask();
const bool allo_sconto = f.get()[0] == 'S';
m.enable(F_TIPOPAG, !allo_sconto);
if (allo_sconto)
m.set(F_TIPOPAG, 2);
}
return true;
}
// Handler per gestire il caricamento degli effetti nella distinta
// in automatico relativamente ad un importo fissato (per la maschera principale)
bool TVariazione_distinte::importo_handler(TMask_field& f, KEY k)
{
// se importo distinta maggiore importo presentato si devono andare a
// caricare effetti in automatico per un valore minore uguale alla
// differenza dei suddetti importi
if (k == K_SPACE)
{
aggiungi();
TSheet_field& sf_riba = f.mask().sfield(F_SHEET_RIBA);
sf_riba.force_update();
}
return true;
}
// Handler per gestire il caricamento degli effetti nella distinta in
// automatico relativamente ad un importo fissato (per la maschera
// secondaria)
bool TVariazione_distinte::imp_sel_handler(TMask_field& f, KEY k)
{
TMask& m2 = f.mask();
// se quando si entra nell maschera il campo contiene un valore
// significa che si deve procedere con il caricamento automatico
// di effetti per l'importo iscritto nel campo
if (k == K_TAB && f.to_check(k, true))
{
TMask* m = app()._msk;
TSheet_field& sf = m2.sfield(F_SHEET);
TSheet_field& sf_riba = m->sfield(F_SHEET_RIBA);
real res = m2.get_real(F_IMPSEL);
if (res > ZERO)
{ // se i due importi sono diversi da zero
TString16 val = m->get(F_CODVAL);
int items = sf.items();
// cerca se esiste un effetto con importo uguale a quello
// da caricare
int i;
for (i = 0; i < items; i++)
{
TToken_string& row = sf.row(i);
TString16 codval = row.get(sf.cid2index(F_VALUTA));
codval.trim();
// se la valuta non appare o <20> lire faccio in modo che vengano
// presi gli effetti con valuta inesistente
const bool valuta = ::is_true_value(codval);
const real imp(row.get(sf.cid2index(valuta ? F_IMPORTOVAL : F_IMPORTO)));
if (imp == res && ::same_values(codval, val))
{
row.add('X', 0);
res = ZERO;
}
}
// se non esiste un effetto con importo uguale a quello
// da caricare carico l'importo sommando pi<70> effetti
for (i = 0; res > ZERO && i < items; i++)
{
TToken_string& row = sf.row(i);
TString4 codval = row.get(sf.cid2index(F_VALUTA));
codval.trim();
const bool valuta = ::is_true_value(codval) ;
const real imp(row.get(sf.cid2index(valuta ? F_IMPORTOVAL : F_IMPORTO)));
// se l'importo, della riga corrente dello sheet, <20> minore
// dell 'importo che si deve caricare e se lo rimane anche
// sommato all'importo gi<67> selezionato, si procede a rendere
// la riga selezionata per il caricamento
if (::same_values(codval, val) && imp <= res)
{
row.add('X',0);
res -= imp;
}
}
sf.force_update();
calcola();
}
}
return true;
}
// Handler per gestire la pressione del bottone conferma della maschera
// per l'aggiunta delle riba (ef0300c)
bool TVariazione_distinte::conferma_handler(TMask_field& f, KEY k)
{
if (k == K_ENTER)
{
TMask* msk = app()._msk;
TSheet_field& sf_riba = msk->sfield(F_SHEET_RIBA);
TMask& m = f.mask();
m.close(); // chiudo la maschera secondaria
// scarico tutte le righe, selezionate, dello sheet della maschera
// secondaria nello sheet della maschera primaria della relap (ef0300a)
TSheet_field& sf = m.sfield(F_SHEET);
FOR_EACH_SHEET_ROW(sf, i, row) if ((*row)[0] == 'X') // selected
{
row->add(" ", 0);
sf_riba.row(-1) = *row;
}
}
return true;
}
// Handler per gestire la pressione del bottone annulla della maschera
// per l'aggiunta delle riba (ef0300c)
bool TVariazione_distinte::annulla_handler(TMask_field& f, KEY k)
{
TMask& m = f.mask();
m.close();
return true;
}
// Handler per gestire la scelta per data, nella maschera di scelta
// delle riba (ef0300c)
bool TVariazione_distinte::data_handler(TMask_field& f, KEY k)
{
if (f.to_check(k) && k == K_TAB)
{
// Carica prima tutte le ri.ba e poi toglie quelle che non servono in base alla selzione
int tipopag = app()._msk->get_int(F_TIPOPAG);
if (tipopag != 0)
carica_riba(tipopag, false);
TMask& m = f.mask();
bool deleted = false;
TDate datad = m.get_date(F_DADATA);
TDate dataa = m.get_date(F_ADATA);
if (!datad.ok())
datad = botime;
if (!dataa.ok())
dataa = eotime;
TDate data_sh;
TSheet_field& sf = m.sfield(F_SHEET);
TString_array& sa = sf.rows_array();
const int field = m.get(F_TIPORD) == "F" ? 6 : 2;
// tolgo dallo sheet gli effetti che hanno la data non compresa nel range
for (int i = sa.items()-1; i >=0 ; i--)
{
TToken_string& row = sa.row(i);
data_sh = (TDate)row.get(field);
if (data_sh > dataa || data_sh < datad)
sa.remove(i);
}
sa.pack();
sf.force_update();
}
return true;
}
// COMPARE FUNCTION per l'ordinamento per data degli effetti presenti
// nello sheet, nella maschera di scelta delle riba (ef0300c)
HIDDEN int confronta_numero(const TObject** o1, const TObject** o2)
{
TToken_string* s1 = (TToken_string*) *o1;
TToken_string* s2 = (TToken_string*) *o2;
const long eff1 = s1->get_long(1);
const long eff2 = s2->get_long(1);
return eff1-eff2;
}
// COMPARE FUNCTION per l'ordinamento per data degli effetti presenti
// nello sheet, nella maschera di scelta delle riba (ef0300c)
HIDDEN int confronta_data(const TObject** o1, const TObject** o2)
{
TToken_string* s1 = (TToken_string*) *o1;
TToken_string* s2 = (TToken_string*) *o2;
const TDate data1 = s1->get(2);
const TDate data2 = s2->get(2);
if (data1 != data2)
return (data1 > data2) ? +1 : -1;
return confronta_numero(o1, o2);
}
// COMPARE FUNCTION per l'ordinamento per numero e data fattura degli
// effetti presenti nello sheet, nella maschera di scelta delle riba
HIDDEN int confronta_fatt(const TObject** o1, const TObject** o2)
{
TToken_string* s1 = (TToken_string*) *o1;
TToken_string* s2 = (TToken_string*) *o2;
const TDate data1 = s1->get(6);
const TDate data2 = s2->get(6);
// ordinamento sulla data fattura
if (data1 != data2)
return (data1 > data2) ? +1 : -1;
return confronta_data(o1, o2);
}
void TVariazione_distinte::ordina(COMPARE_FUNCTION cf)
{
TWait_cursor hourglass;
TSheet_field& sf = app()._m2->sfield(F_SHEET);
// scarico le righe dello sheet in un array
TArray& effetti = sf.rows_array();
effetti.sort(cf);// ordino gli elementi dell'array
sf.force_update();
}
// Handler per gestire i diversi ordinamenti, nella maschera di scelta
// delle riba (ef0300c)
bool TVariazione_distinte::ordina_handler(TMask_field& f, KEY k)
{
if (k == K_SPACE && f.mask().is_running())
{
switch(f.get()[0])
{
case 'S': ordina(confronta_data); break; //ordino gli effetti nello sheet per data
case 'F': ordina(confronta_fatt); break; //ordino gli effetti nello sheet per fattura
default : ordina(confronta_numero); break; //ordino gli effetti nello sheet per numero
}
}
return true;
}
bool TVariazione_distinte::uncontabilize_handler(TMask_field& f, KEY k)
{
if (k == K_SPACE)
{
TMask& m = f.mask();
const char tipodist = m.get(F_TIPODIST)[0];
const long numdist = m.get_long(F_NUMBER);
if (yesno_box(TR("Si desidera annullare la contabilizzazione della distinta %ld?"), numdist))
{
TRelation rel(LF_EFFETTI);
TRectype& rec = rel.curr();
rec.put(EFF_TIPODIST, tipodist);
rec.put(EFF_NDIST,numdist);
TCursor cur(&rel, "", 4, &rec, &rec);
const TRecnotype items = cur.items();
cur.freeze();
TAssoc_array movs;
for (cur = 0; cur.pos() < items; ++cur)
{
movs.add(rec.get(EFF_NUMREG));
rec.zero(EFF_EFFCONT);
rec.zero(EFF_NUMREG);
rel.rewrite();
}
if (movs.items() > 0)
{
TString msg;
msg = TR("E' necessario cancellare i seguenti movimenti contabili:\n");
FOR_EACH_ASSOC_OBJECT(movs, hash, key, obj)
msg << key << ' ';
warning_box(msg);
}
m.stop_run(K_ESC);
}
}
return true;
}
// Metodo che calcola i totali relativi alla distinta (totale in
// lire e totale in valuta(se presente)) nella maschera principale
void TVariazione_distinte::calcola_totale()
{
TMask* m = app()._msk;
TSheet_field& sf = m->sfield(F_SHEET_RIBA);
const int items = sf.items();
real impdist;
const TString& codval = m->get(F_CODVAL);
const bool valuta = ::is_true_value(codval);
for (int i = 0; i < items; i++)
{
TToken_string& row = sf.row(i);
// se l'effetto <20> selezionato per l'eliminazione tolgo il suo importo
// dal totale presentazione della distinta
if (row.get_char(0) != 'X') // valido (not to delete)
{
const real imp = row.get(sf.cid2index(valuta ? F_IMPORTOVAL : F_IMPORTO));
impdist += imp;
}
}
m->set(F_TOTIMP, impdist);
}
// Notify per il calcolo dei totali relativi alla selezione effetti
bool TVariazione_distinte::dist_check_handler(TMask_field& f, KEY key)
{
if (key == K_SPACE)
{
TSheet_field& s = app().righe_sheet();
TToken_string& row = s.row(s.selected());
const bool checked = f.get().not_empty();
row.add(checked ? "X" : "", 0);
app().calcola_totale();
}
return true;
}
// Metodo che calcola i totali relativi alla selezione effetti per la
// distinta nella maschera di scelta delle riba (ef0300c)
void TVariazione_distinte::calcola()
{
TMask& m2 = *app()._m2;
TSheet_field& sf = m2.sfield(F_SHEET);
const bool valuta = ::is_true_value(m2.get(F_CODVALS));
const int imp_col = sf.cid2index(valuta ? F_IMPORTOVAL : F_IMPORTO); // Colonna con importo
real impsel;
FOR_EACH_SHEET_ROW(sf, i, row)
{
// se l'effetto <20> selezionato aggiungo il suo importo al totale importo selezionato
if (row->get_char(0) == 'X')
impsel += real(row->get(imp_col));
}
m2.set(F_IMPSEL, impsel);
const real imp_pres = app()._msk->get_real(F_TOTIMP);
m2.set(F_TOTIMPDIST, real(imp_pres+impsel));
}
// Notify per il calcolo dei totali relativi alla selezione effetti
// per la distinta nella maschera di scelta delle riba (ef0300c)
bool TVariazione_distinte::check_handler(TMask_field& f, KEY key)
{
if (key == K_SPACE)
{
TSheet_field& s = app().righe_sel_sheet();
TToken_string& row = s.row(s.selected());
const bool checked = f.get().full();
row.add(checked ? "X" : "", 0);
app().calcola();
}
return true;
}
// Metodo che permette di aggiungere effetti alla distinta caricandoli
// tra quelli non ancora assegnati, chiamato quando si aggiunge una
// riga allo sheet degli effetti della distinta
void TVariazione_distinte::aggiungi()
{
TMask* m = app()._msk;
TMask* m2 = app()._m2;
int tipopag = m->get_int(F_TIPOPAG);
if (tipopag != 0)
carica_riba(tipopag);
m2->set(F_CODVALS, m->get(F_CODVAL));
calcola();
m2->run();
calcola_totale();
}
// Notify per il calcolo dei totali relativi alla distinta
// nella maschera della relap (ef0300a)
bool TVariazione_distinte::impdist_notify(TSheet_field& s, int r, KEY key)
{
if (key == K_INS)
{
aggiungi();
s.force_update();
return false;
}
return true;
}
bool TVariazione_distinte::impdist_handler(TMask_field& f, KEY key)
{
bool ok = true;
if (key == K_ENTER && f.mask().get_int(F_TIPOPAG) == 8) // RID
{
TSheet_field& sf = (TSheet_field&)f;
if (sf.items() > 1)
{
char tipoa = ' ';
int autodel = -1;
TString8 key;
TLocalisamfile eff(LF_EFFETTI);
FOR_EACH_SHEET_ROW(sf, r, riga) if (riga->get_char(0) != 'X') // riga valida (NON da eliminare)
{
eff.put(EFF_NPROGTR, riga->get(1));
if (eff.read() == NOERR)
{
const char tipocf = eff.get_char(EFF_TIPOCF);
const long codcf = eff.get_long(EFF_CODCF);
key.format("%c|%ld", tipocf, codcf);
char ta = cache().get(LF_CLIFO, key, CLI_TIPOAPER)[0];
if (ta != 'G') ta = 'F'; // Fisica o giuridica
if (tipoa < 'F') tipoa = ta; // Imposta tipo standard, se ignoto
if (tipoa != ta)
{
if (autodel != 1)
{
ok = error_box(FR("Tipo anagrafica non valido alla riga %d:\n"
"Non possono coesistere RID relativi a persone Fisiche e Giuridiche"),
r+1);
if (autodel < 0)
autodel = yesno_box("Si desidera impostare l'eliminazione delle righe incompatibili?");
}
if (autodel == 1)
riga->add('X', 0);
}
}
}
if (!ok && autodel)
sf.force_update();
}
}
return ok;
}
bool TVariazione_distinte::imp_notify(TSheet_field& s, int r, KEY key)
{
return !(key == K_DEL || key == K_INS);
}
int ef0300(int argc, char* argv[])
{
TVariazione_distinte a ;
a.run(argc, argv, TR("Distinte di presentazione"));
return 0;
}