campo-sirio/ca/ca1800.cpp
luca b7537b29c6 Patch level :10.0
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :sistemati filtri sulla maschera in modo da accettare intervalli di tipo da conto a conto (senza sottoconto)


git-svn-id: svn://10.65.10.50/trunk@19767 c028cbd2-c16b-5b4b-a496-9718f37d4682
2009-12-14 14:48:21 +00:00

412 lines
11 KiB
C++
Executable File

#include <applicat.h>
#include <automask.h>
#include <defmask.h>
#include <dongle.h>
#include <modaut.h>
#include <progind.h>
#include <recset.h>
#include <reprint.h>
#include <textset.h>
#include <utility.h>
#include "rmovana.h"
#include "calib01.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")
{
const bool has_ca = dongle().active(CAAUT);
//se la chiave ha CA mostra i campi gruppo 2 (codice e descrizione commessa)..
if (has_ca)
{
hide(-1);
show(-2);
//se le fasi sono figlie di nessuno può visualizzare il gruppo 3 (da fase a fase)
TConfig& cfg = ca_config();
const TString& fath_fasi = cfg.get("FathFasi");
if (fath_fasi.empty())
show(-3);
else
hide(-3);
}
else //..se invece ha CM mostra i campi gruppo 1 (da cms a cms) e gruppo 3 (da fase a fase)
{
hide(-2);
show(-1);
show(-3);
}
}
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 TAnal_report
{
protected:
virtual bool use_mask() { return false; }
public:
TPrint_contixcms_report() {}
};
////////////////////////////////////////////////////////
// RECORDSET
////////////////////////////////////////////////////////
class TPrint_contixcms_recordset : public TAS400_recordset
{
protected:
long trova_riga(const TString& 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à
long TPrint_contixcms_recordset::trova_riga(const TString& key)
{
long first = 0;
long last = items() - 1;
long riga = -1;
TString80 guess_key;
while(first <= last)
{
const long guess = (first + last) / 2;
move_to(guess);
guess_key = get(RMOVANA_CODCMS).as_string(); //commessa
guess_key.left_just(20);
guess_key << 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();
//solo i conti di tipo costo/ricavo possono essere considerati (no attività/passività o non definiti)
if (ib == ib_costi || ib == ib_ricavi)
{
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 è solo un filtro in input)
TString80 key;
key = codcms;
key.left_just(20);
key << codconto;
//cerca se per caso la riga non esista già 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 è 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;
bool _has_ca;
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";
if (_has_ca)
query << "SELECT (BETWEEN(CODCMS,#CODCMS,#CODCMS))&&(BETWEEN(CODCONTO,#DACODCONTO,#ACODCONTO))\n";
else
query << "SELECT (BETWEEN(CODCMS,#DACODCMS,#ACODCMS))&&(BETWEEN(CODFASE,#DACODFASE,#ACODFASE))&&(BETWEEN(CODCONTO,#DACODCONTO,#ACODCONTO))\n";
query << "FROM DATACOMP=#DADATA\n";
query << "TO DATACOMP=#ADATA";
TISAM_recordset recset(query);
if (_has_ca)
recset.set_var("#CODCMS", TVariant(_mask->get(F_CODCMS)));
else
{
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 è contabile e non analitico ed è 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);
if (gruppo == 0)
gruppo = 999;
conto = _mask->get_int(F_CONTOFIN);
if (conto == 0)
conto = 999;
sottoconto = _mask->get_long(F_SOTTOCFIN);
if (sottoconto == 0)
sottoconto = 999999L;
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ù 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ò scegliere che report usare (personalizzato!)
TString rep_name = _mask->get(F_REPORT);
//se il rep non è selezionato usa quello standard
if (rep_name.empty())
rep_name << "ca1800a.rep";
TPrint_contixcms_report rep;
rep.load(rep_name);
//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);
//setta i valori della maschera sul report (dopo la set_recordset, sennò..
//..sarebbero sovrascritti dalla set_recordset)
rep.mask2report(*_mask);
//se l'utonto vuole il dettaglio sottocontesco
if (_mask->get_bool(F_HIDESOTT))
rep.section('B', 1).hide();
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()
{
//controlla se la chiave ha il modulo CA (e non solo CM) NON è ammesso CA E CM
_has_ca = dongle().active(CAAUT);
//in tal caso il programma è utilizzabile solo se si ha il piano dei conti contabile..
if (_has_ca)
{
TConfig& cfg = ca_config();
const bool usepdcc = cfg.get_bool("UsePdcc");
if (!usepdcc)
return error_box(TR("Il programma non è utilizzabile con la corrente configurazione CA!"));
}
return TSkeleton_application::create();
}
int ca1800(int argc, char* argv[])
{
TPrint_contixcms a;
a.run(argc, argv, TR("Stampa conti per commessa"));
return 0;
}