campo-sirio/m770/770200.cpp

739 lines
20 KiB
C++
Raw Normal View History

// 770200 - collegamento 1a nota (versamento) - ritenuta percipienti
#include <applicat.h>
#include <assoc.h>
#include <currency.h>
#include <mailbox.h>
#include <mask.h>
#include <progind.h>
#include <relation.h>
#include <sheet.h>
#include <urldefid.h>
#include "77lib.h"
#include "770200a.h"
class TVersa_rit : public TSkeleton_application
{
private:
TLink770 _coll;
real _versato;
TRelation* _rel;
TCursor* _cur;
TCursor_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 void main_loop();
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,
const real& versato);
void attach_pag_vers(TToken_string& r, real& versato, bool last);
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()
{
// simulo una chiamata da contabilit<69>
// (lo lascio per eventuali prove)
// real totdocla = ZERO;
// real spesela = ZERO;
// real compensola = ZERO;
// real impostela = ZERO;
// real ritenutela = 70000;
// TToken_string s(80);
// s.add(4);
// s.add("M");
// s.add("F");
// s.add(30010);
// s.add(1);
// s.add("2");
// s.add("02-09-1997");
// s.add(totdocla.string());
// s.add(spesela.string());
// s.add(compensola.string());
// s.add(impostela.string());
// s.add(ritenutela.string());
// const char* name = "770 -1";
// TMessage mla(name, "LINK770", s);
// mla.send();
// 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());
_sheet_perc = new TCursor_sheet(_cur,
" |TIPOA|CODANAGR|6->RAGSOC",
"Selezione percipienti",
"@1|Tipo|Codice|Ragione sociale@50",
8, 3);
_schede = new TArray_sheet(3, 3, -3, -3,
"Selezione schede",
"@1|T|Codice|Scheda n.|Data@10|Ragione@50");
_pagam = new TArray_sheet(3, 3, -3, -3,
"Selezione ritenute da versare",
"@1|T|Codice|Scheda n.|Riga n.|Ritenuta@18V");
_apags.destroy();
return TSkeleton_application::create();
}
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))
if (luogo == ' ' || luogo == '\0')
f.warning_box("Indicare il luogo del versamento");
}
return TRUE;
}
bool TVersa_rit::abicab_hndl(TMask_field& f, KEY k)
{
if (f.to_check(k))
{
TMask& m = f.mask();
const char tipo = m.get(F_TIPO)[0];
// ABI/CAB solo se tipo e' B
if (tipo != 'B')
return TRUE;
const TString& park = f.get();
for (int i=0; park[i]; 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(3);
TToken_string* tpag = find(codditta,tipoa,codanagr,nprog);
if (!tpag) continue;
while ( (nriga = tpag->get_int()) != 0 ) // le righe partono da 1
{
const 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(nprog);
rr.add(nriga);
rr.add(da_versare.string()); // Importo senza punti e virgole !!!!!!!!!!!!!
_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(nprog);
rr.add(datadoc);
rr.add(ragsoc);
_schede->add(rr);
}
sch.next();
}
} // if checked
}
bool TVersa_rit::do_all()
{
long items = 0L;
// esecuzione prima maschera: richiesta estremi versamento
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);
}
}
// loop di gestione sheet di scelta percipiente,
// scelta scheda e scelta pagamento da versare
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;
}
}
else
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;
}
}
else
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
const long totchk = _pagam->checked();
if (totchk > 0)
{
long chk = 0L;
for (int i=0; i < _pagam->items() && _versato > ZERO; i++) if (_pagam->checked(i))
{
chk++;
const bool is_last_checked = (chk == totchk);
TToken_string& r = _pagam->row(i);
attach_pag_vers(r, _versato, is_last_checked);
}
return warning_box("Creazione di %d versamenti terminata", chk);
}
} // while (TRUE)
return TRUE;
}
void TVersa_rit::attach_pag_vers(TToken_string& r, real& disponibile, bool is_last)
{
const long codditta = get_firm();
const 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 real da_versare = r.get(5); // importo ancora "scoperto" in questo pag.
real vers_corr;
// Se e' l'ultimo pagamento metto tutto l'importo del versamento
if (is_last)
vers_corr = disponibile;
else
vers_corr = (disponibile > da_versare) ? da_versare : disponibile;
disponibile -= vers_corr; // Scalo versamento corrente
const long new_vers = add_new_vers(codditta,tipoa,codanagr,nprog,vers_corr);
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("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);
rpag.zero();
rpag.put("CODDITTA", codditta);
rpag.put("TIPOA", tipoa);
rpag.put("CODANAGR", codanagr);
rpag.put("NPROG", nprog);
rpag.put("NRIGA", nriga);
int ret_code = rpag.read();
if (ret_code != NOERR)
{
error_box("Pagamento non trovato. Errore %d", ret_code);
return ret_code;
}
rpag.put("NUMVERS", new_vers);
ret_code = rpag.rewrite();
if (ret_code != NOERR)
{
error_box("Pagamento non modificato. Errore %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,
const 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", codditta);
rver.put("TIPOA", tipoa);
rver.put("CODANAGR", 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)
{
error_box("Fallita creazione versamento. Errore %d", rver.status());
return 0L;
}
TLocalisamfile scperc(LF_SCPERC);
scperc.zero();
scperc.put("CODDITTA", codditta);
scperc.put("TIPOA", tipoa);
scperc.put("CODANAGR", codanagr);
scperc.put("NPROG", nprog);
if (scperc.read() == NOERR)
{
real ritver = scperc.get("RITVER");
ritver += versata;
scperc.put("RITVER", ritver);
scperc.rewrite();
}
return nriga;
}
void TVersa_rit::main_loop()
{
do_all();
}
int collega_vers_rit(int argc, char* argv[])
{
TVersa_rit a;
a.run(argc, argv, "Versamento ritenute");
return 0;
}