campo-sirio/pr/pr0800.cpp
guy 1f2e7c2c82 Corretto calcolo provvigioni negative generate da note di credito
git-svn-id: svn://10.65.10.50/branches/R_10_00@22735 c028cbd2-c16b-5b4b-a496-9718f37d4682
2012-09-26 10:41:35 +00:00

260 lines
7.5 KiB
C++
Executable File

// Programma di gestione provvigioni
#include <applicat.h>
#include <automask.h>
#include <recset.h>
#include "../cg/cgsaldac.h"
#include "prlib.h"
#include <modaut.h>
#include <mov.h>
#include <doc.h>
#include "provv.h"
#include "pr0800a.h"
#include "pr0.h"
class TAggiornamento_maturato_mask : public TAutomask
{
protected:
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
public:
void load_params();
void save_params();
TAggiornamento_maturato_mask() : TAutomask("pr0800a") {}
};
bool TAggiornamento_maturato_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
{
case F_A_CODAGE:
if (e == fe_close)
{
const long a_cod = atol(o.get());
const long da_cod = get_long(F_DA_CODAGE);
if (a_cod > 0L && da_cod > a_cod)
return error_box(TR("Codice agente finale minore del codice agente iniziale"));
}
break;
case F_CHECK_INSOLUTI:
if (e == fe_init)
{
const TRectype prov(LF_PROVV);
o.enable(prov.exist(PROV_DATASTAMPA));
}
break;
default:
break;
}
return true;
}
class TAggiornamento_maturato_app : public TSkeleton_application
{
protected:
virtual bool create();
virtual void main_loop();
public:
void aggiorna_maturato(const TAggiornamento_maturato_mask &m);
};
////////////////////////////////////////////////////////////////////////////////////////
// Da fare :
// - Quando si elimina l'ultima riga dello spreadsheet si posiziona sulla prima senza
// mandare un K_TAB per aggiornare le rate
// - Browse dei documenti in ricerca, quando si seleziona setta giustamente focusdirty() e manda
// un K_TAB. Quando si tenta di uscire dal campo si ha ancora il campo focusdirty()
// - Cercare di implementare scarico/saldo righe provvigionali per agente in base ad una
// impostata
// - Ultimo ma non meno importante (da ritenersi visualmente valido) lo riempimento fisso
// degli sheet (documenti e rate) in modo da evitare il fastidiosissimo sfarfallio in
// inserimento righe con elementi vuoti
////////////////////////////////////////////////////////////////////////////////////////
bool TAggiornamento_maturato_app::create()
{
const bool saldaconto = has_module(SCAUT, CHK_DONGLE);
if (!saldaconto)
return error_box(TR("Questo programma necessita del saldaconto"));
open_files(LF_PROVV, LF_TABCOM, LF_DOC, LF_PARTITE, LF_SCADENZE, LF_PAGSCA, LF_TAB, 0);
return TSkeleton_application::create();
}
static bool prov_saldata(const TRectype& prov)
{
bool is_saldata = prov.get_bool(PROV_SALDATA);
if (!is_saldata)
{
const real importo_rata = prov.get(PROV_IMPRATA);
const real importo_pagato = prov.get(PROV_PAGATO);
if ((importo_rata > ZERO) && (importo_rata <= importo_pagato)) // come fosse saldata, per cui ...
is_saldata = true;
}
return is_saldata;
}
static bool scan_func(const TRelation& rel, void* pJolly)
{
const TAggiornamento_maturato_mask& m = *(const TAggiornamento_maturato_mask*)pJolly;
TRectype& rec = rel.curr();
const bool is_saldata = prov_saldata(rec);
bool check_insoluti = false;
TDate data_stampa;
if (is_saldata && m.get_bool(F_CHECK_INSOLUTI))
{
data_stampa = rec.get_date(PROV_DATASTAMPA);
check_insoluti = data_stampa.ok();
}
if (!check_insoluti && is_saldata)
return true;
const int anno = rec.get_int(PROV_ANNO);
const TString& codnum(rec.get(PROV_CODNUM)) ;
const long ndoc = rec.get_long(PROV_NDOC);
TString80 key; key.format("D|%d|%s|%ld", anno, (const char *) codnum, ndoc);
const long nreg = atol(cache().get(LF_DOC, key, DOC_NUMREG));
if (nreg <= 0)
return true; // nessuna partita???
const TDate data_scad = m.get(F_DATA_SCAD);
TDate data_rischio(data_scad); data_rischio -= m.get_long(F_GIORNI_RISCHIO);
TPartite_array partite;
partite.add_numreg(nreg); // Always 1 record
bool changed_record = false;
for (const TPartita* part = partite.first(); part && !changed_record; part = partite.next()) // Always 1 game
{
bool insoluti_in_ritardo = false;
for (int nriga = part->last(); nriga > 0 && !changed_record; nriga = part->pred(nriga))
{
const TRiga_partite& r = part->riga(nriga);
if (check_insoluti && r.tipo() >= tm_insoluto)
{
const TDate data_insoluto = r.get(PART_DATAREG);
if (data_insoluto > data_stampa)
insoluti_in_ritardo = true;
continue;
}
if (r.get_long(PART_NREG) != nreg || r.tipo() > tm_nota_credito)
continue;
if (rec.get_bool(PROV_SALDATA))
{
if (check_insoluti && !insoluti_in_ritardo)
continue; // Ignora righe saldate in assenza di insoluti
}
int nrata = rec.get_int(PROV_NRATA);
if (nrata > 0 && !r.exist(nrata))
nrata = 0;
const real importo_rata(rec.get_real(PROV_IMPRATA));
const real importo_pagato(rec.get_real(PROV_PAGATO));
const real provvigione_rata(rec.get_real(PROV_IMPPROVV));
const real provvigione_pagata(rec.get_real(PROV_PROVVPAG));
if (nrata > 0)
{
bool sbf = false;
const TRiga_scadenze& s = r.rata(nrata);
TImporto pagato(s.importo_pagato(false));
pagato -= s.esposto(false, data_scad, data_rischio, sbf);
pagato.normalize('A');
if (pagato.valore() >= importo_rata)
{
const real importo_maturato = importo_rata - importo_pagato;
const real provvigione_maturata = provvigione_rata - provvigione_pagata;
rec.put(PROV_PAGMAT, importo_maturato);
rec.put(PROV_PROVVMAT, provvigione_maturata);
changed_record = true;
}
else
{
real importo_maturato = pagato.valore() - importo_pagato;
if (importo_maturato < ZERO)
{
if (-importo_maturato > importo_pagato)
importo_maturato = -importo_pagato;
}
if (importo_maturato >= ZERO)
{
real provvigione_maturata = provvigione_rata * importo_maturato / importo_rata;
provvigione_maturata.round(2);
rec.put(PROV_PAGMAT, importo_maturato);
rec.put(PROV_PROVVMAT, provvigione_maturata);
changed_record = true;
}
}
}
else
{
const TDate data_mat = rec.get_date(PROV_DATASCAD);
if (data_mat <= data_scad)
{
changed_record = true;
rec.put(PROV_PAGMAT, importo_rata);
rec.put(PROV_PROVVMAT, provvigione_rata);
}
}
if (changed_record)
{
TLocalisamfile provv(LF_PROVV);
provv.curr() = rec;
int err = provv.read(_isequal, _lock);
if (err == NOERR)
err = rec.rewrite(provv);
if (err != NOERR)
return yesno_box(FR("Errore %d in aggioramento agente %ld, Continuare ugualmente"), err, rec.get_long(PROV_CODAGE));
}
}
}
return true;
}
void TAggiornamento_maturato_app::aggiorna_maturato(const TAggiornamento_maturato_mask &m)
{
const bool check_insoluti = m.get_bool(F_CHECK_INSOLUTI);
TString filter = "(ANNO!=\"\")&&(CODNUM!=\"\")&&(NDOC!=\"\")";
if (!check_insoluti)
filter << "&&(SALDATA!=\"X\")";
TRectype from(LF_PROVV), to(LF_PROVV);
from.put(PROV_CODAGE, m.get(F_DA_CODAGE));
to.put(PROV_CODAGE, m.get(F_A_CODAGE));
TRelation rel(LF_PROVV);
TCursor c(&rel, filter, 1, &from, &to);
c.setregion(from, to);
c.scan(scan_func, (void*)&m, TR("Aggiornamento provvigioni maturate"));
}
void TAggiornamento_maturato_app::main_loop()
{
TAggiornamento_maturato_mask m;
while (m.run() == K_ENTER)
aggiorna_maturato(m);
}
int pr0800(int argc, char** argv)
{
TAggiornamento_maturato_app a;
a.run(argc, argv, TR("Aggiornamento provvigioni maturate"));
return 0;
}