campo-sirio/m770/770200.cpp
nik a1095f6e04 Cazzo, cazzeggio e controcazzeggio!
Prime modifiche per utilizzare le nuove maschere (upgrade R9604/R9605)


git-svn-id: svn://10.65.10.50/trunk@3889 c028cbd2-c16b-5b4b-a496-9718f37d4682
1996-11-12 09:52:22 +00:00

739 lines
20 KiB
C++
Executable File

// 770200 - collegamento 1a nota (versamento) - ritenuta percipienti
#include <applicat.h>
#include <assoc.h>
#include <relation.h>
#include <progind.h>
#include <urldefid.h>
#include <sheet.h>
#include <mask.h>
#include <maskfld.h>
#include <mailbox.h>
#include "77lib.h"
#include "770200a.h"
class TVersa_rit : public TApplication
{
private:
TLink770 _coll;
real _versato;
TRelation* _rel;
TCursor* _cur;
TBrowse_sheet* _sheet_perc;
TArray_sheet* _schede;
TArray_sheet* _pagam;
TMask* _msk;
TLocalisamfile* _perc, *_scperc, *_rpag, *_rver;
TAssoc_array _apags;
// Estremi versamento
TString16 _data, _serie, _numero;
char _luogo, _tipo;
void add(const long codditta, char tipoa, const long codanagr,
const int nprog, TToken_string& rriga);
TToken_string* find(const long codditta, char tipoa, const long codanagr,
const int nprog);
void remove(const long codditta, char tipoa, const long codanagr,
const int nprog);
static void work_tipoluogo(TMask_field& f);
static bool luo_hndl (TMask_field& f, KEY k);
static bool tipo_hndl(TMask_field& f, KEY k);
static bool abicab_hndl(TMask_field& f, KEY k);
protected:
virtual bool create();
virtual bool destroy();
virtual bool menu(MENU_TAG m);
int split_rpag(const long codditta,char tipoa,
const long codanagr, const int nprog,
const int nriga, real& versato, real& da_versare,
const long newvers);
int attach_rpag(const long codditta, char tipoa,
const long codanagr, const int nprog,
const int nriga, const long new_vers);
long add_new_vers(const long codditta, char tipoa,
const long codanagr, const int nprog,
real& versato);
void attach_pag_vers(TToken_string& r, real& versato, const bool last=FALSE);
real ritenuta_versata(const long codditta,const long numvers);
bool ha_pagamenti_non_versati(const long codditta,
char tipoa,const long codanagr,const int nprog);
TCursor* meik_curs(TRelation* rel);
bool do_all();
void build_schede_sheet(const long codditta);
void build_pagam_sheet(const long codditta);
public:
TVersa_rit() {}
~TVersa_rit() {}
};
TCursor* TVersa_rit::meik_curs(TRelation* rel)
{
TString16 filt;
TCursor* cur;
const long codditta = get_firm();
filt.format("CODDITTA=%ld", codditta);
cur = new TCursor(rel, filt);
return cur;
}
bool TVersa_rit::create()
{
TApplication::create();
// Collegamento da contabilita'
TMailbox m;
TMessage* msg = m.next_s("LINK770");
// Questo programma si richiama solo dalla contabilita'
if (!msg) return FALSE;
if ( !_coll.read(msg->body()) )
return warning_box("Errore nei parametri passati");
_perc = new TLocalisamfile(LF_PERC);
_scperc = new TLocalisamfile(LF_SCPERC);
_rpag = new TLocalisamfile(LF_RPAG);
_rver = new TLocalisamfile(LF_RVER);
_rel = new TRelation(LF_PERC);
_rel->add(LF_ANAG, "TIPOA=TIPOA|CODANAGR=CODANAGR");
_cur = meik_curs(_rel);
_msk = new TMask("770200a");
_msk->set_handler(F_LUOGO, luo_hndl);
_msk->set_handler(F_TIPO, tipo_hndl);
_msk->set_handler(F_SERIE, abicab_hndl);
_msk->set_handler(F_NUMERO, abicab_hndl);
_msk->set(F_DATA, _coll._datadoc);
_msk->set(F_VERSATO, _coll._ritenute.string());
KEY kp = _msk->run();
if (kp != K_ENTER)
return FALSE;
else
{
_data = _msk->get(F_DATA);
_luogo = _msk->get(F_LUOGO)[0];
_tipo = _msk->get(F_TIPO)[0];
_versato = real(_msk->get(F_VERSATO));
if (_tipo == DELEGA_BANCARIA)
{
_serie = _msk->get(F_ABI);
_numero = _msk->get(F_CAB);
}
else
{
_serie = _msk->get(F_SERIE);
_numero = _msk->get(F_NUMERO);
}
}
TEdit_field& dummy = (TEdit_field&)_msk->field(F_CODANAGRPERC);
TToken_string siblings; // non ho ricerche alternative
_sheet_perc = new TBrowse_sheet(_cur," |TIPOA|CODANAGR|6->RAGSOC", "Selezione percipienti",
"@1|Tipo|Codice|Ragione sociale@50", 8, &dummy,siblings);
_sheet_perc->maximize();
_schede = new TArray_sheet(-1, -1, 0, 0, "Selezione Schede","@1|T|Codice|Ragione@50|N.|Data@10");
_schede->maximize();
_pagam = new TArray_sheet(-1, -1, 0, 0, "Selezione Ritenute da versare",
"@1|T|Codice|Scheda n.|Riga n.|Ritenuta@15");
_pagam->maximize();
_apags.destroy();
dispatch_e_menu (BAR_ITEM(1));
return TRUE;
}
bool TVersa_rit::destroy()
{
delete _rel;
delete _cur;
delete _msk;
delete _schede;
delete _pagam;
delete _sheet_perc;
delete _rver; delete _rpag; delete _scperc; delete _perc;
return TApplication::destroy();
}
void TVersa_rit::work_tipoluogo(TMask_field& f)
{
TMask& m = f.mask();
char tipo = m.get(F_TIPO)[0];
char luogo = m.get(F_LUOGO)[0];
m.hide (-2); // nasconde tutto
if (tipo == 'D')
{
if (luogo == 'T')
m.show(-3); // SOLO quietanza
else
m.show(-4); // serie e numero
}
else
if (tipo == 'B')
m.show (-6); // ABI e CAB
else
if (tipo == 'C')
m.show (-5); // SOLO numero versamento
}
bool TVersa_rit::luo_hndl(TMask_field& f, KEY k)
{
if (k == K_TAB)
work_tipoluogo(f);
if (k == K_ENTER)
{
TMask& m = f.mask();
char tipo = m.get(F_TIPO)[0];
char luogo = m.get(F_LUOGO)[0];
// Se ho indicato il luogo => devo indicare anche il TIPO
if (isalpha(luogo))
return tipo == ' ' || tipo == '\0' ?
f.warning_box("Indicare il tipo del versamento") : TRUE;
}
return TRUE;
}
bool TVersa_rit::tipo_hndl(TMask_field& f, KEY k)
{
if (k == K_TAB)
work_tipoluogo(f);
if (k == K_ENTER || k == K_TAB)
{
TMask& m = f.mask();
char tipo = m.get(F_TIPO)[0];
char luogo = m.get(F_LUOGO)[0];
// Se ho indicato il tipo => devo indicare anche il LUOGO
if (isalpha(tipo))
return luogo == ' ' || luogo == '\0' ?
f.warning_box("Indicare il luogo del versamento") : TRUE;
}
return TRUE;
}
bool TVersa_rit::abicab_hndl(TMask_field& f, KEY k)
{
if (f.to_check(k))
{
TString16 park(f.get());
TMask& m = f.mask();
char tipo = m.get(F_TIPO)[0];
// ABI/CAB solo se tipo e' B
if (tipo != 'B')
return TRUE;
for (int i=0; i<park.len(); i++)
if (!isdigit(park[i]))
return f.warning_box("Il codice ABI/CAB deve essere numerico");
}
return TRUE;
}
real TVersa_rit::ritenuta_versata(const long codditta,const long numvers)
{
TLocalisamfile rver(LF_RVER);
real versato = ZERO;
rver.zero();
rver.setkey(2);
rver.put("CODDITTA", (long)codditta);
// rver.put("NUMVERS", (long)numvers);
if (rver.read() == NOERR)
versato = rver.get_real("RITENUTA");
return versato;
}
void TVersa_rit::add(const long codditta, char tipoa, const long codanagr,
const int nprog, TToken_string& rrr)
{
TString80 key;
key.format("%5ld%c%5ld%d", codditta,tipoa,codanagr,nprog);
_apags.add(key, rrr);
}
TToken_string* TVersa_rit::find(const long codditta, char tipoa,
const long codanagr, const int nprog)
{
TString80 key;
key.format("%5ld%c%5ld%d", codditta,tipoa,codanagr,nprog);
TToken_string* rr = (TToken_string*)_apags.objptr(key);
return rr;
}
void TVersa_rit::remove(const long codditta, char tipoa, const long codanagr,
const int nprog)
{
TString80 key;
key.format("%5ld%c%5ld%d", codditta,tipoa,codanagr,nprog);
_apags.remove(key);
}
bool TVersa_rit::ha_pagamenti_non_versati(const long codditta,char tipoa,const long codanagr,const int nprog)
{
TLocalisamfile rpag(LF_RPAG);
bool found = FALSE;
long numvers = 0L;
real ritvers = ZERO, ritpag = ZERO;
int nriga = 0;
rpag.zero();
rpag.put("CODDITTA", (long)codditta);
rpag.put("TIPOA", tipoa);
rpag.put("CODANAGR", (long)codanagr);
rpag.put("NPROG", nprog);
TRectype dep(rpag.curr());
TToken_string rriga(80);
rpag.read(_isgteq);
while (rpag.curr() == dep && !rpag.eof())
{
numvers = rpag.get_long("NUMVERS");
nriga = rpag.get_int("NRIGA");
ritpag = rpag.get_real("RITENUTA");
if (numvers <= 0)
{
found = TRUE;
rriga.add(nriga);
rriga.add(ritpag.string());
}
/* 4.7.95 Considero solo i pagamenti NON collegati
else
{
ritvers = ritenuta_versata(codditta,numvers);
real resto = ritpag - ritvers;
if (resto > ZERO)
{
found = TRUE;
rriga.add(nriga);
rriga.add(resto.string());
}
}
***************************************************************/
rpag.next();
}
if (found) add(codditta,tipoa,codanagr,nprog,rriga);
return found;
}
void TVersa_rit::build_pagam_sheet(const long codditta)
{
_pagam->destroy();
// build array_sheet dei pagamenti non collegati o non del tutto versati
int nriga = 0;
for (int i=0; i < _schede->items(); i++)
if (_schede->checked(i))
{
TToken_string& r = _schede->row(i);
char tipoa = r.get_char(1);
long codanagr = r.get_long(2);
const int nprog = r.get_int(4);
TToken_string* tpag = find(codditta,tipoa,codanagr,nprog);
if (!tpag) continue;
while ( (nriga = tpag->get_int()) != 0 ) // le righe partono da 1
{
real da_versare(tpag->get()); // leggo importo rimasto da versare
TToken_string rr(100);
rr.add(" "); // Spazio per selezionare
rr.add(tipoa);
rr.add(codanagr);
// rr.add(ragsoc);
rr.add(nprog);
rr.add(nriga);
rr.add(da_versare.string());
_pagam->add(rr);
}
}
}
void TVersa_rit::build_schede_sheet(const long codditta)
{
// Costruisco lista schede
_schede->destroy();
TLocalisamfile sch(LF_SCPERC);
sch.setkey(1);
for (int i=0; i<_sheet_perc->items(); i++)
if (_sheet_perc->checked(i))
{
// Leggo tipo e codice del percipiente selezionato
TToken_string& r = _sheet_perc->row(i);
char tipoa = r.get_char(1);
long codanagr = r.get_long(2);
TString80 ragsoc(r.get(3));
sch.zero();
sch.put("CODDITTA", (long)codditta);
sch.put("TIPOA", tipoa);
sch.put("CODANAGR", codanagr);
TRectype dep(sch.curr());
// Leggo tutte le schede del percipiente scelto
sch.read(_isgteq);
while (sch.curr() == dep && !sch.eof())
{
const int nprog = sch.get_int("NPROG");
TString16 datadoc(sch.get("DATADOC"));
// Considero solo le schede con pagamenti non ancora versati
if (ha_pagamenti_non_versati(codditta,tipoa,codanagr,nprog))
{
TToken_string rr(100);
rr.add(" "); // Spazio per selezionare
rr.add(tipoa);
rr.add(codanagr);
rr.add(ragsoc);
rr.add(nprog);
rr.add(datadoc);
_schede->add(rr);
}
sch.next();
}
} // if checked
}
bool TVersa_rit::do_all()
{
KEY kp;
long items = 0L;
while (TRUE)
{
items = _sheet_perc->items();
if (items == 0L)
{
warning_box("Nessun percipiente registrato");
return FALSE;
}
kp = _sheet_perc->run();
if (kp == K_ENTER)
if (!_sheet_perc->one_checked())
{
warning_box("Nessun percipiente selezionato");
continue;
}
if (kp == K_ESC)
return FALSE;
const long selected = _sheet_perc->selected();
const long codditta = get_firm();
build_schede_sheet(codditta);
items = _schede->items();
if (items == 0L)
{
warning_box("Non esistono pagamenti non versati per i percipienti selezionati");
continue;
}
kp = _schede->run();
if (kp == K_ENTER)
if (!_schede->one_checked())
{
warning_box("Nessuna scheda selezionata");
continue;
}
if (kp == K_ESC)
continue;
build_pagam_sheet(codditta);
kp = _pagam->run();
if (kp == K_ENTER)
if (!_pagam->one_checked())
{
warning_box("Nessun pagamento selezionato");
continue;
}
if (kp == K_ESC)
continue;
// Leggo importo arrivato dalla contabilita'
// _versato = _coll._totdoc;
// Distribuisce _versato sui pagamenti selezionati creando la riga di
// versamento se occorre
long chk = 0L;
for (int i=0; i < _pagam->items(); i++)
if (_pagam->checked(i))
{
chk++;
if (_versato == ZERO) break;
// Sull'ultimo pagamento metto tutto il versamento rimasto
const bool last_checked = chk == _pagam->checked();
TToken_string& r = _pagam->row(i);
real da_versare(r.get(5));
attach_pag_vers(r, _versato, last_checked);
if (da_versare > _versato)
_versato = ZERO;
else
_versato -= da_versare;
}
return warning_box("Creazione versamenti terminata");
} // while (TRUE)
return TRUE;
}
void TVersa_rit::attach_pag_vers(TToken_string& r, real& versato, const bool last)
{
char tipoa = r.get_char(1);
const long codanagr = r.get_long(2);
const int nprog = r.get_int(3);
const int nriga = r.get_int(4);
const long codditta = get_firm();
real da_versare(r.get(5)); // importo ancora "scoperto" in questo pag.
/*************************************************************************
TLocalisamfile rpag(LF_RPAG);
rpag.setkey(1);
rpag.zero();
rpag.put("CODDITTA", (long)codditta);
rpag.put("TIPOA", tipoa);
rpag.put("CODANAGR", (long)codanagr);
rpag.put("NPROG", nprog);
rpag.put("NRIGA", nriga);
if (rpag.read() != NOERR) return; // Non dovrebbe succedere mai
// Decido l'importo da attribuire al nuovo versamento
real ritenuta = rpag.get_real("RITENUTA");
*************************************************************************/
real vers_corr = ZERO;
// Se e' l'ultimo pagamento metto tutto l'importo del versamento
if (last)
vers_corr = versato;
else
vers_corr = versato > da_versare ? da_versare : versato;
// const long numvers = rpag.get_long("NUMVERS");
const long new_vers = add_new_vers(codditta,tipoa,codanagr,nprog,vers_corr);
// Se il pagamento era gia' collegato ad un versamento lo divido in due
// pagamenti: uno lo lascio collegato al precedente versamento, l'altro
// collegato al nuovo.
// Ogni pagamento puo' essere collegato A UNO E UNO SOLO versamento
/******
if (numvers > 0)
split_rpag(codditta,tipoa,codanagr,nprog,nriga,versato,da_versare,new_vers);
else
*****/
attach_rpag(codditta,tipoa,codanagr,nprog,nriga,new_vers);
}
int TVersa_rit::split_rpag(const long codditta,char tipoa,
const long codanagr, const int nprog,
const int nriga, real& versato, real& da_versare,
const long new_vers)
{
TLocalisamfile rpag(LF_RPAG);
long numpag = 0L;
long pag = 0L;
int new_riga = 0;
int ret_code = 0;
// Determino un nuovo NUMPAG
for (rpag.first(); !rpag.eof(); rpag.next())
{
pag = rpag.get_long("NUMPAG");
if (pag > numpag) numpag = pag;
}
numpag++;
// Determino un nuovo NRIGA
rpag.zero();
rpag.put("CODDITTA", (long)codditta);
rpag.put("TIPOA", tipoa);
rpag.put("CODANAGR", (long)codanagr);
rpag.put("NPROG", nprog);
TRectype dep(rpag.curr());
rpag.read(_isgteq);
while (rpag.curr() == dep && !rpag.eof())
{
new_riga = rpag.get_int("NRIGA");
rpag.next();
}
new_riga++;
// Sposto il pagamento preesistente
rpag.zero();
rpag.put("CODDITTA", (long)codditta);
rpag.put("TIPOA", tipoa);
rpag.put("CODANAGR", (long)codanagr);
rpag.put("NPROG", nprog);
rpag.put("NRIGA", nriga);
if ((ret_code = rpag.read()) != NOERR)
return ret_code;
// Leggo ritenuta del vecchio record e il suo versamento eventuale
// La parte che era stata gia' versata resta con il vecchio record
// La parte versata ora viene registrata nel nuovo.
real ritenuta = rpag.get_real("RITENUTA");
real parte_versata = ritenuta - da_versare;
TRectype salvo(rpag.curr());
rpag.zero();
rpag.curr() = salvo;
// Cambio solo: NUMPAG, NRIGA, e aggiorno la ritenuta. NUMVERS resta uguale
rpag.put("NUMPAG", (long)numpag);
rpag.put("NRIGA", new_riga);
rpag.put("RITENUTA", parte_versata);
// Registro il vecchio pagamento nella nuova posizione
if ((ret_code = rpag.write()) != NOERR)
warning_box("Pagamento non inserito. Codice %d", ret_code);
// Modifico l'originale per puntare al nuovo versamento
rpag.zero();
rpag.curr() = salvo;
rpag.put("NUMVERS", (long) new_vers);
rpag.put("RITENUTA", da_versare);
// Salvo le modifiche al vecchio pagamento
if ((ret_code = rpag.rewrite()) != NOERR)
warning_box("Pagamento non modificato. Codice %d", ret_code);
return ret_code;
}
int TVersa_rit::attach_rpag(const long codditta, char tipoa,
const long codanagr, const int nprog,
const int nriga, const long new_vers)
{
TLocalisamfile rpag(LF_RPAG);
int ret_code = 0;
rpag.zero();
rpag.put("CODDITTA", (long)codditta);
rpag.put("TIPOA", tipoa);
rpag.put("CODANAGR", (long)codanagr);
rpag.put("NPROG", nprog);
rpag.put("NRIGA", nriga);
if ((ret_code = rpag.read()) != NOERR)
{
warning_box("Pagamento non trovato. Codice %d", ret_code);
return ret_code;
}
rpag.put("NUMVERS", (long)new_vers);
if ((ret_code = rpag.rewrite()) != NOERR)
{
warning_box("Pagamento non modificato. Codice %d", ret_code);
return ret_code;
}
return ret_code;
}
long TVersa_rit::add_new_vers(const long codditta, char tipoa,
const long codanagr, const int nprog,
real& versata)
{
TLocalisamfile rver(LF_RVER);
int nriga = 0;
// Determino un numero di riga nuovo
rver.zero();
rver.put("CODDITTA", (long)codditta);
rver.put("TIPOA", tipoa);
rver.put("CODANAGR", (long)codanagr);
rver.put("NPROG", nprog);
TRectype dep(rver.curr());
rver.read(_isgteq);
while (rver.curr() == dep && !rver.eof())
{
nriga = rver.get_int("NRIGA");
rver.next();
}
nriga++;
// Scrivo il nuovo record
rver.zero();
rver.put("CODDITTA", (long)codditta);
rver.put("TIPOA", tipoa);
rver.put("CODANAGR", (long)codanagr);
rver.put("NPROG", nprog);
rver.put("NRIGA", nriga);
// rver.put("NUMVERS", (long)nriga);
rver.put("DATAVERS", _data);
rver.put("LUOVERS", _luogo);
rver.put("TIPOVERS", _tipo);
rver.put("SERIE", _serie);
rver.put("NUMERO", _numero);
rver.put("RITENUTA", versata);
if (rver.write() != NOERR)
{
warning_box("Fallita creazione versamento. Codice %d", rver.status());
return 0L;
}
return nriga;
}
bool TVersa_rit::menu(MENU_TAG m)
{
if (m == BAR_ITEM(1))
return do_all();
return FALSE;
}
int collega_vers_rit(int argc, char* argv[])
{
TVersa_rit a;
a.run(argc, argv, "Versamento ritenute");
return 0;
}