352 lines
9.5 KiB
C++
352 lines
9.5 KiB
C++
|
#include <applicat.h>
|
|||
|
#include <automask.h>
|
|||
|
#include <defmask.h>
|
|||
|
#include <progind.h>
|
|||
|
#include <recset.h>
|
|||
|
#include <reprint.h>
|
|||
|
#include <textset.h>
|
|||
|
#include <utility.h>
|
|||
|
|
|||
|
#include "rmovana.h"
|
|||
|
#include "calib02.h"
|
|||
|
#include "ca1800a.h"
|
|||
|
|
|||
|
////////////////////////////////////////////////////////
|
|||
|
// MASCHERA
|
|||
|
////////////////////////////////////////////////////////
|
|||
|
class TPrint_contixcms_mask : public TAutomask
|
|||
|
{
|
|||
|
protected:
|
|||
|
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
|
|||
|
public:
|
|||
|
TPrint_contixcms_mask();
|
|||
|
};
|
|||
|
|
|||
|
TPrint_contixcms_mask::TPrint_contixcms_mask() : TAutomask("ca1800a")
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
bool TPrint_contixcms_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
|||
|
{
|
|||
|
switch(o.dlg())
|
|||
|
{
|
|||
|
case DLG_PRINT:
|
|||
|
if (e == fe_button)
|
|||
|
{
|
|||
|
main_app().print();
|
|||
|
return false;
|
|||
|
}
|
|||
|
break;
|
|||
|
case DLG_PREVIEW:
|
|||
|
if (e == fe_button)
|
|||
|
{
|
|||
|
main_app().preview();
|
|||
|
return false;
|
|||
|
}
|
|||
|
break;
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
////////////////////////////////////////////////////////
|
|||
|
// REPORT
|
|||
|
////////////////////////////////////////////////////////
|
|||
|
class TPrint_contixcms_report : public TReport
|
|||
|
{
|
|||
|
protected:
|
|||
|
//virtual bool use_mask() { return false; } //questo ci vuole quando la maschera ha un nome != dai report
|
|||
|
public:
|
|||
|
TPrint_contixcms_report() {}
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
////////////////////////////////////////////////////////
|
|||
|
// RECORDSET
|
|||
|
////////////////////////////////////////////////////////
|
|||
|
class TPrint_contixcms_recordset : public TAS400_recordset
|
|||
|
{
|
|||
|
protected:
|
|||
|
long trova_riga(const TToken_string& key);
|
|||
|
|
|||
|
public:
|
|||
|
bool aggiungi_riga(TISAM_recordset& recset);
|
|||
|
TPrint_contixcms_recordset();
|
|||
|
};
|
|||
|
|
|||
|
TPrint_contixcms_recordset::TPrint_contixcms_recordset()
|
|||
|
: TAS400_recordset("AS400(80)")
|
|||
|
{
|
|||
|
create_field(RMOVANA_CODCMS, -1, 20, _alfafld, true);
|
|||
|
create_field(RMOVANA_CODFASE, -1, 10, _alfafld, false);
|
|||
|
create_field(RMOVANA_CODCONTO, -1, 12, _alfafld, true);
|
|||
|
create_field("INDBIL", -1, 1, _intfld, true);
|
|||
|
create_field(RMOVANA_DATACOMP, -1, 8, _datefld, true);
|
|||
|
create_field(RMOVANA_IMPORTO, -1, 18, _realfld, true);
|
|||
|
create_field(RMOVANA_SEZIONE, -1, 1, _alfafld, true);
|
|||
|
}
|
|||
|
|
|||
|
//cerca se una riga con chiave key esiste gi<67>
|
|||
|
long TPrint_contixcms_recordset::trova_riga(const TToken_string& key)
|
|||
|
{
|
|||
|
long first = 0;
|
|||
|
long last = items() - 1;
|
|||
|
long riga = -1;
|
|||
|
|
|||
|
while(first <= last)
|
|||
|
{
|
|||
|
const long guess = (first + last) / 2;
|
|||
|
move_to(guess);
|
|||
|
|
|||
|
TToken_string guess_key;
|
|||
|
guess_key.add(get(RMOVANA_CODCMS).as_string()); //commessa
|
|||
|
guess_key.add(get(RMOVANA_CODCONTO).as_string()); //conto
|
|||
|
|
|||
|
const int diff = guess_key.compare(key);
|
|||
|
if (diff == 0)
|
|||
|
{
|
|||
|
riga = guess;
|
|||
|
break;
|
|||
|
}
|
|||
|
if (diff > 0)
|
|||
|
{
|
|||
|
last = guess - 1;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
first = guess + 1;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return riga;
|
|||
|
}
|
|||
|
|
|||
|
//funzione di ordinamento per il campo codcms/codconto
|
|||
|
//sono 2 stringhe
|
|||
|
static int compare_cms_conto(const TObject** o1, const TObject** o2)
|
|||
|
{
|
|||
|
TString& s1 = *(TString*)*o1;
|
|||
|
TString& s2 = *(TString*)*o2;
|
|||
|
|
|||
|
const TString& cms1 = s1.left(20);
|
|||
|
const TString& cms2 = s2.left(20);
|
|||
|
|
|||
|
int cmp = cms1.compare(cms2);
|
|||
|
|
|||
|
if (cmp == 0)
|
|||
|
{
|
|||
|
const TString& cnt1 = s1.mid(30, 12);
|
|||
|
const TString& cnt2 = s2.mid(30, 12);
|
|||
|
|
|||
|
cmp = cnt1.compare(cnt2);
|
|||
|
}
|
|||
|
|
|||
|
return cmp;
|
|||
|
}
|
|||
|
|
|||
|
//metodo per aggiungere righe al recordset da stampare
|
|||
|
bool TPrint_contixcms_recordset::aggiungi_riga(TISAM_recordset& recset)
|
|||
|
{
|
|||
|
//raccatta i dati che servono alla riga da stampare prendendoli dal record corrente del..
|
|||
|
//..recordset in esame riempito dalla query iniziale
|
|||
|
const TString& codcms = recset.get(RMOVANA_CODCMS).as_string();
|
|||
|
const TString& codfase = recset.get(RMOVANA_CODFASE).as_string();
|
|||
|
const TString& codconto = recset.get(RMOVANA_CODCONTO).as_string();
|
|||
|
TAnal_bill zio(codconto);
|
|||
|
const TIndbil ib = zio.indicatore_bilancio();
|
|||
|
const TDate& datacomp = recset.get(RMOVANA_DATACOMP).as_date();
|
|||
|
const real curr_valore = recset.get(RMOVANA_IMPORTO).as_real();
|
|||
|
const char curr_sezione = recset.get(RMOVANA_SEZIONE).as_string()[0];
|
|||
|
TImporto curr_imp(curr_sezione, curr_valore); //importo riga correntemente in esame
|
|||
|
|
|||
|
//chiave della riga (solo su commessa e conto!; la fase <20> solo un filtro in input)
|
|||
|
TToken_string key;
|
|||
|
key.add(codcms);
|
|||
|
key.add(codconto);
|
|||
|
|
|||
|
//cerca se per caso la riga non esista gi<67> con questa chiave
|
|||
|
long numriga = trova_riga(key);
|
|||
|
|
|||
|
//se la riga con la chiave key non esiste nel printrecordset la aggiunge
|
|||
|
if (numriga < 0)
|
|||
|
{
|
|||
|
new_rec("");
|
|||
|
set(RMOVANA_CODCMS, TVariant(codcms));
|
|||
|
set(RMOVANA_CODFASE, TVariant(codfase));
|
|||
|
set(RMOVANA_CODCONTO, TVariant(codconto));
|
|||
|
set("INDBIL", TVariant(long(ib)));
|
|||
|
set(RMOVANA_DATACOMP, TVariant(datacomp));
|
|||
|
|
|||
|
//deve ordinare il recordset
|
|||
|
sort(compare_cms_conto);
|
|||
|
|
|||
|
//dopo che la riga <20> stata aggiunta riesegue la trova_riga in modo da ottenere il numero di riga
|
|||
|
numriga = trova_riga(key);
|
|||
|
}
|
|||
|
|
|||
|
//importo riga con indice numriga
|
|||
|
const char tot_sezione = get(RMOVANA_SEZIONE).as_string()[0];
|
|||
|
const real tot_valore = get(RMOVANA_IMPORTO).as_real();
|
|||
|
TImporto tot_imp(tot_sezione, tot_valore);
|
|||
|
|
|||
|
//aggiunge l'importo alla riga (nuova o vecchia)
|
|||
|
tot_imp += curr_imp;
|
|||
|
|
|||
|
//normalizza e risalva il valore aggiornato sulla riga
|
|||
|
tot_imp.normalize();
|
|||
|
TString4 str_sez;
|
|||
|
str_sez << tot_imp.sezione();
|
|||
|
set(RMOVANA_SEZIONE, str_sez);
|
|||
|
set(RMOVANA_IMPORTO, tot_imp.valore());
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
////////////////////////////////////////////////////////
|
|||
|
// APPLICAZIONE
|
|||
|
////////////////////////////////////////////////////////
|
|||
|
class TPrint_contixcms : public TSkeleton_application
|
|||
|
{
|
|||
|
TPrint_contixcms_mask* _mask;
|
|||
|
|
|||
|
protected:
|
|||
|
virtual const char * extra_modules() const {return "cm";} //funziona anche con autorizzazione CM
|
|||
|
|
|||
|
virtual bool create();
|
|||
|
virtual void print();
|
|||
|
virtual void preview();
|
|||
|
virtual void print_or_preview(const bool stampa);
|
|||
|
|
|||
|
TPrint_contixcms_recordset* elabora() const;
|
|||
|
|
|||
|
public:
|
|||
|
virtual void main_loop();
|
|||
|
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
//metodo di alto livello per la gestione dell'elaborazione
|
|||
|
TPrint_contixcms_recordset* TPrint_contixcms::elabora() const
|
|||
|
{
|
|||
|
//creazione dell'as400 recordset che verra' riempito dai record del recordset righe
|
|||
|
TPrint_contixcms_recordset* printset = new TPrint_contixcms_recordset();
|
|||
|
|
|||
|
//creazione della query per la creazione del recordset
|
|||
|
TString query;
|
|||
|
query << "USE RMOVANA KEY 3\n";
|
|||
|
query << "SELECT (BETWEEN(CODCMS,#DACODCMS,#ACODCMS))&&(BETWEEN(CODFASE,#DACODFASE,#ACODFASE))&&(BETWEEN(CODCONTO,#DACODCONTO,#ACODCONTO))\n";
|
|||
|
//query << "JOIN MOVANA INTO NUMREG==NUMREG\n";
|
|||
|
//query << "JOIN PCON INTO GRUPPO=CODCONTO[1,3] CONTO=CODCONTO[4,6] SOTTOCONTO=CODCONTO[7,12]\n";
|
|||
|
query << "FROM DATACOMP=#DADATA\n";
|
|||
|
query << "TO DATACOMP=#ADATA";
|
|||
|
|
|||
|
TISAM_recordset recset(query);
|
|||
|
|
|||
|
recset.set_var("#DACODCMS", TVariant(_mask->get(F_DACODCMS)));
|
|||
|
recset.set_var("#ACODCMS", TVariant(_mask->get(F_ACODCMS)));
|
|||
|
recset.set_var("#DACODFASE", TVariant(_mask->get(F_DACODFASE)));
|
|||
|
recset.set_var("#ACODFASE", TVariant(_mask->get(F_ACODFASE)));
|
|||
|
|
|||
|
//per il conto va gestito il fatto che il conto <20> contabile e non analitico ed <20> 0-filled
|
|||
|
TString contone;
|
|||
|
|
|||
|
int gruppo = _mask->get_int(F_GRUPPOINI);
|
|||
|
int conto = _mask->get_int(F_CONTOINI);
|
|||
|
long sottoconto = _mask->get_long(F_SOTTOCINI);
|
|||
|
contone.format("%03d%03d%06ld", gruppo, conto, sottoconto);
|
|||
|
recset.set_var("#DACODCONTO", contone);
|
|||
|
|
|||
|
gruppo = _mask->get_int(F_GRUPPOFIN);
|
|||
|
conto = _mask->get_int(F_CONTOFIN);
|
|||
|
sottoconto = _mask->get_long(F_SOTTOCFIN);
|
|||
|
contone.format("%03d%03d%06ld", gruppo, conto, sottoconto);
|
|||
|
recset.set_var("#ACODCONTO", contone);
|
|||
|
|
|||
|
//e alla fine le decisivissime date (che sono l'intervallo di scelta pi<70> importante)
|
|||
|
recset.set_var("#DADATA", _mask->get_date(F_DATAINI));
|
|||
|
recset.set_var("#ADATA", _mask->get_date(F_DATAFIN));
|
|||
|
|
|||
|
//se ci sono record che soddisfano le pesanti richieste dell'utonto...
|
|||
|
const long recset_items = recset.items();
|
|||
|
if (recset_items > 0)
|
|||
|
{
|
|||
|
//E crea pure la progind..
|
|||
|
TProgind pi(recset_items, TR("Elaborazione dati per la stampa..."), true, true);
|
|||
|
|
|||
|
//Scansione del recordset trovato
|
|||
|
for (bool ok = recset.move_first(); ok; ok = recset.move_next())
|
|||
|
{
|
|||
|
if (!pi.addstatus(1))
|
|||
|
break;
|
|||
|
//scrive sul CSV i campi che servono al report
|
|||
|
printset->aggiungi_riga(recset);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return printset;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//fantastico metodo per gestire stampa o anteprima
|
|||
|
void TPrint_contixcms::print_or_preview(const bool stampa)
|
|||
|
{
|
|||
|
if (_mask->check_fields())
|
|||
|
{
|
|||
|
//l'utonto pu<70> scegliere che report usare (personalizzato!)
|
|||
|
TString rep_name = _mask->get(F_REPORT);
|
|||
|
//se il rep non <20> selezionato usa quello standard
|
|||
|
if (rep_name.empty())
|
|||
|
rep_name << "ca1800a.rep";
|
|||
|
|
|||
|
TPrint_contixcms_report rep;
|
|||
|
rep.load(rep_name);
|
|||
|
|
|||
|
rep.mask2report(*_mask); //setta i valori della maschera sul report
|
|||
|
|
|||
|
//metodo per la generazione del recordset che contiene tutti i dati da stampare
|
|||
|
//insomma, il vero programma!
|
|||
|
TPrint_contixcms_recordset* printset = elabora();
|
|||
|
|
|||
|
//appioppa il recordset al report
|
|||
|
rep.set_recordset(printset);
|
|||
|
|
|||
|
TReport_book book;
|
|||
|
book.add(rep);
|
|||
|
if (stampa)
|
|||
|
book.print();
|
|||
|
else
|
|||
|
book.preview();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void TPrint_contixcms::print()
|
|||
|
{
|
|||
|
print_or_preview(true);
|
|||
|
}
|
|||
|
|
|||
|
void TPrint_contixcms::preview()
|
|||
|
{
|
|||
|
print_or_preview(false);
|
|||
|
}
|
|||
|
|
|||
|
void TPrint_contixcms::main_loop()
|
|||
|
{
|
|||
|
_mask = new TPrint_contixcms_mask;
|
|||
|
_mask->run();
|
|||
|
delete _mask;
|
|||
|
_mask = NULL;
|
|||
|
}
|
|||
|
|
|||
|
bool TPrint_contixcms::create()
|
|||
|
{
|
|||
|
return TSkeleton_application::create();
|
|||
|
}
|
|||
|
|
|||
|
int ca1800(int argc, char* argv[])
|
|||
|
{
|
|||
|
TPrint_contixcms a;
|
|||
|
a.run(argc, argv, TR("Stampa saldi conti per commessa"));
|
|||
|
return 0;
|
|||
|
}
|