Files correlati : f151.dir f151.trr ca1.exe ca2.exe ca3.exe ca3100.uml ca3100a.rep ca3100b.rep ca3200.uml ca3200a.rep ca3200b.rep ca3300.uml ca3300a.rep ca3300b.rep ca3300c.rep ca3300d.rep ca3600.uml ca3600a.rep ca3700.uml ca3700a.rep ca3700b.rep ca3800.uml ca3800a.rep ca3800as.rep ca3800b.rep ca3800bs.rep ca3800c.rep ca3800cs.rep ca3883.cpp ca3900.uml ca3900a.rep Commento : Aggiunta contabilità separata alle stampe di analitica. Aggiunto meccanismo per lanciare le stampe in batch. Sintassi: ca3 -7 -b <nome del file che contiene i valori dell maschera> <tipo di output <P>rint|<E>xport|E<X>cel|PD<F>|<T>esto|<D>Base|<V>isualizza> <nome del file di output Esempio: ca3 -7 -b select.sav X c:\out\rend esporta il rendiconto di commessa usando i parametri salvati in select.sav nel file c:\out\rend.xls
1247 lines
41 KiB
C++
Executable File
1247 lines
41 KiB
C++
Executable File
#include <applicat.h>
|
||
#include <defmask.h>
|
||
#include <execp.h>
|
||
#include <progind.h>
|
||
#include <recarray.h>
|
||
#include <repapp.h>
|
||
|
||
#include <clifo.h>
|
||
#include <mov.h>
|
||
#include <partite.h>
|
||
#include <rmov.h>
|
||
#include <rmoviva.h>
|
||
|
||
#include "..\cg\cgsaldac.h"
|
||
#include "..\cg\cglib.h"
|
||
|
||
#include "pconana.h"
|
||
#include "commesse.h"
|
||
#include "cdc.h"
|
||
#include "fasi.h"
|
||
#include "movana.h"
|
||
#include "rmovana.h"
|
||
|
||
#include "ca3.h"
|
||
#include "ca3600.h"
|
||
#include "calib01.h"
|
||
#include "calib02.h"
|
||
#include "camask.h"
|
||
|
||
|
||
//===============================================================================================
|
||
////////////////////////////////////////////////////////
|
||
// MASCHERA
|
||
////////////////////////////////////////////////////////
|
||
|
||
class TPag_per_cms_mask: public TAnal_report_mask
|
||
{
|
||
protected:
|
||
virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly);
|
||
void config_loader(TSheet_field& sf, const char* paragrafo);
|
||
void config_setter(TSheet_field& sf, const char* paragrafo);
|
||
|
||
public:
|
||
TPag_per_cms_mask();
|
||
virtual ~TPag_per_cms_mask() {}
|
||
|
||
};
|
||
|
||
bool TPag_per_cms_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
|
||
{
|
||
switch (o.dlg())
|
||
{
|
||
case DLG_SAVEREC:
|
||
if (e == fe_button)
|
||
{
|
||
config_setter(sfield(F_PDCC), "Pdcc");
|
||
// config_setter(sfield(F_PDCA), "Pdca"); ***per ora solo Pdcc***
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
return TAnal_report_mask::on_field_event(o, e, jolly);
|
||
}
|
||
|
||
TPag_per_cms_mask::TPag_per_cms_mask()
|
||
:TAnal_report_mask("ca3600")
|
||
{
|
||
//Prima pagina
|
||
// creazione dei campi della pagina della maschera con lo sheet di cdc/cms/fasi
|
||
create_sheet(F_RIGHE);
|
||
|
||
//carica i parametri dei conti per lo sheet dei conti contabili
|
||
config_loader(sfield(F_PDCC), "Pdcc");
|
||
// setta gli handlers a tutti i campi generati della maschera;senza questa chiamata la on_field_event
|
||
// non puo' funzionare sui campi generati!!!
|
||
set_handlers();
|
||
}
|
||
|
||
void TPag_per_cms_mask::config_loader(TSheet_field& sf, const char* paragrafo)
|
||
{
|
||
TFilename configname = "ca3600a.ini"; //carica file configurazione conti
|
||
configname.custom_path();
|
||
TConfig configfile(configname, paragrafo);
|
||
|
||
TString_array conti;
|
||
|
||
configfile.list_variables(conti, false, paragrafo, true);
|
||
FOR_EACH_ARRAY_ROW(conti, i, row)
|
||
{
|
||
sf.row(-1) = configfile.get(*row); //carica la riga del .ini senza il contatore
|
||
sf.check_row(i);
|
||
}
|
||
}
|
||
|
||
void TPag_per_cms_mask::config_setter(TSheet_field& sf, const char* paragrafo)
|
||
{
|
||
TFilename configname = "ca3600a.ini"; //carica file configurazione conti
|
||
configname.custom_path();
|
||
TConfig configfile(configname, paragrafo);
|
||
|
||
configfile.remove_all(); //svuota il paragrafo sul .ini prima di ricompilarlo (se non si facesse
|
||
//non si riuscirebbero ad ammazzare le righe sul .ini
|
||
FOR_EACH_SHEET_ROW (sf, i, row)
|
||
{
|
||
TToken_string conto("");
|
||
conto.add(row->get(0));
|
||
conto.add(row->get(1));
|
||
conto.add(row->get(2));
|
||
conto.add(row->get(3)); //*****nel caso di pdca deve tener conto dei livelli variabili
|
||
|
||
configfile.set("conto", conto, NULL, true, i);
|
||
}
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////////
|
||
// RECORDSET
|
||
///////////////////////////////////////////////////////////////
|
||
class TPag_per_cms_recordset : public TISAM_recordset
|
||
{
|
||
TExternisamfile* _tmp;
|
||
|
||
protected:
|
||
TDate _dadata, _adata;
|
||
long _dacodfor, _acodfor;
|
||
TString16 _campodata;
|
||
TString _codcosto, _codcms, _codfas, _contsep;
|
||
TAssoc_array _costi,_pagamenti,_fiscali,_sociali; //array che contengono i conti letti dal .ini
|
||
|
||
|
||
protected: //da libreria
|
||
virtual const TVariant& get(const char* column_name) const;
|
||
|
||
protected:
|
||
void crea_trr(const TFilename& trr) const;
|
||
static bool part_callback(const TRelation& rel, void* pJolly);
|
||
static bool mov_callback(const TRelation& rel, void* pJolly);
|
||
long find_movimento(const TRectype& riga_pag) const;
|
||
void find_commesse(const long nreg, const TRectype& riga_pag);
|
||
void find_commesse_cg(const TRectype& mov);
|
||
bool check_cms_cdc_fsc(const TRectype& rec_analriga);
|
||
const TString& query_movama_by_numregcg(const long nreg);
|
||
void lettura_conti(TAssoc_array& assoc, const char tipoconto);
|
||
int cerca_riga_fattura_origine(const TPartita& match, const TRectype& riga_pag);
|
||
real totale_documento(const TRectype& mov) const;
|
||
real calcola_pagato_prec(const TPartita& match, const int riga_fatt, const TRectype& riga_pag);
|
||
bool test_swap(TCausale& caus, bool ritsoc) const;
|
||
bool cerca_conto(const char tipo, const TBill& bill, const TAssoc_array& assoc) const;
|
||
int cerca_costo(const TBill& bill) const;
|
||
int cerca_pagamento(const TBill& bill) const;
|
||
bool cerca_fiscali(const TBill& bill) const;
|
||
bool cerca_sociali(const TBill& bill) const;
|
||
|
||
public:
|
||
virtual void set_filter(const TPag_per_cms_mask& msk, const int cms_row, const long dacodfor, const long acodfor, const TString& campodata);
|
||
virtual void set_custom_filter(TCursor& cur) const;
|
||
void scan_pags();
|
||
void scan_movs();
|
||
|
||
TPag_per_cms_recordset(const TString& sql) : TISAM_recordset(sql) { _tmp = NULL;}
|
||
~TPag_per_cms_recordset();
|
||
};
|
||
|
||
//////////////////////////////////
|
||
// generica
|
||
//////////////////////////////////
|
||
static TPag_per_cms_recordset* myself = NULL;
|
||
|
||
TPag_per_cms_recordset::~TPag_per_cms_recordset()
|
||
{ }
|
||
|
||
|
||
void TPag_per_cms_recordset::set_custom_filter(TCursor& cur) const
|
||
{
|
||
relation()->replace(_tmp); //sostituisce il vero file rmovana con quello temporaneo
|
||
|
||
//filtro sul file esterno (_tmp, cio<69> 1000) sui conti selezionati sulla maschera
|
||
TRectype darec(cur.curr()), arec(cur.curr()); //curr perch<63> <20> il file externisamfile
|
||
darec.zero();
|
||
arec.zero();
|
||
|
||
//filtro sulla data(non avendo anche codnum non ho la chiave completa per mettere la data nella setregion)
|
||
TString filtro;
|
||
TString80 f;
|
||
if (_dadata.ok())
|
||
{
|
||
f.format("(ANSI(%s)>=\"%s\")", (const char*)_campodata, _dadata.string(ANSI));
|
||
filtro << f;
|
||
}
|
||
if (_adata.ok())
|
||
{
|
||
if (filtro.not_empty())
|
||
filtro << "&&";
|
||
f.format("(ANSI(%s)<=\"%s\")", (const char*)_campodata, _adata.string(ANSI));
|
||
filtro << f;
|
||
}
|
||
cur.setregion(darec, arec);
|
||
cur.setfilter(filtro);
|
||
|
||
myself = (TPag_per_cms_recordset*)this;
|
||
}
|
||
|
||
//simpatico metodo per riempire in automatico i campi di intestazione speciali
|
||
const TVariant& TPag_per_cms_recordset::get(const char* column_name) const
|
||
{
|
||
|
||
if (*column_name == '#')
|
||
{
|
||
if (strcmp(column_name, "#COSTO") == 0)
|
||
return get_tmp_var() = _codcosto;
|
||
else
|
||
if (strcmp(column_name, "#COMMESSA") == 0)
|
||
return get_tmp_var() = _codcms;
|
||
else
|
||
if (strcmp(column_name, "#FASE") == 0)
|
||
return get_tmp_var() = _codfas;
|
||
else
|
||
if (strcmp(column_name, "#CONTSEP") == 0)
|
||
return get_tmp_var() = _contsep;
|
||
}
|
||
return TISAM_recordset::get(column_name);
|
||
}
|
||
|
||
void TPag_per_cms_recordset::crea_trr(const TFilename& trr) const
|
||
{
|
||
TString chiave;
|
||
ofstream of(trr);
|
||
of << 1000 << endl;
|
||
of << 16 << endl;
|
||
of << "CODFORN|3|6|0|Codice fornitore" << endl;
|
||
of << "DESFORN|1|50|0|Descrizione fornitore" << endl;
|
||
of << "NREG|3|7|0|Numero registrazione" << endl;
|
||
of << "DATAREG|5|8|0|Data registrazione" << endl;
|
||
of << "DATAPAG|5|8|0|Data pagamento" << endl;
|
||
of << "DESCRPAG|1|50|0|Descrizione pagamento" << endl;
|
||
of << "NDOC|1|6|0|Numero documento" << endl;
|
||
of << "DATADOC|5|8|0|Data documento" << endl;
|
||
of << "PROT|2|5|0|Protocollo iva" << endl;
|
||
of << "TOTDOC|4|18|5|Totale documento" << endl;
|
||
of << "TOTPAG|4|18|5|Totale pagamento" << endl;
|
||
of << "TOTRES|4|18|5|Totale residuo" << endl;
|
||
of << "CDC|1|20|0|Centro di costo" << endl;
|
||
of << "CMS|1|20|0|Commessa" << endl;
|
||
of << "FSC|1|10|0|Fase" << endl;
|
||
of << "HIDDEN|8|1|0|Record nascosto" << endl;
|
||
of << 1 << endl;
|
||
//l'ordinamento dipende dal tipo di data selezionato sulla maschera
|
||
chiave << "CODFORN+FSC+NREG+";
|
||
chiave << _campodata;
|
||
of << chiave << endl;
|
||
}
|
||
|
||
void TPag_per_cms_recordset::lettura_conti(TAssoc_array& assoc, const char tipoconto)
|
||
{
|
||
TConfig conti("ca3600a.ini","Pdcc"); //paragrafo da scandire nell'ini (solo conti contabili!!)
|
||
TAssoc_array& vars = conti.list_variables();
|
||
|
||
FOR_EACH_ASSOC_STRING(vars, h, k, val) //riempie l'assoc con i soli valori del paragrafo dell'ini
|
||
{
|
||
if (*val == tipoconto) //mette nell'assocarray solo i conti corrispondenti al tipoconto passato
|
||
assoc.add(val);
|
||
}
|
||
}
|
||
|
||
bool TPag_per_cms_recordset::cerca_conto(const char tipo, const TBill& bill, const TAssoc_array& assoc) const
|
||
{
|
||
TToken_string key(15);
|
||
|
||
key.add(tipo);
|
||
|
||
key.add(bill.gruppo());
|
||
if (assoc.is_key(key))
|
||
return true;
|
||
|
||
key.add(bill.conto());
|
||
if (assoc.is_key(key))
|
||
return true;
|
||
|
||
key.add(bill.sottoconto());
|
||
if (assoc.is_key(key))
|
||
return true;
|
||
|
||
return false;
|
||
}
|
||
|
||
int TPag_per_cms_recordset::cerca_costo(const TBill& bill) const
|
||
{
|
||
if (cerca_conto('C', bill, _costi))
|
||
return 1;
|
||
else
|
||
return 0;
|
||
}
|
||
|
||
int TPag_per_cms_recordset::cerca_pagamento(const TBill& bill) const
|
||
{
|
||
if (cerca_conto('P', bill, _pagamenti))
|
||
return 2;
|
||
else
|
||
return 0;
|
||
}
|
||
|
||
bool TPag_per_cms_recordset::cerca_fiscali(const TBill& bill) const
|
||
{
|
||
return cerca_conto('F', bill, _fiscali);
|
||
}
|
||
|
||
bool TPag_per_cms_recordset::cerca_sociali(const TBill& bill) const
|
||
{
|
||
return cerca_conto('S', bill, _sociali);
|
||
}
|
||
|
||
// Controlla sulla causale se il segno del totale documento (ritsoc=FALSE)
|
||
// o quello delle ritenute sociali (ritsoc=TRUE) e' invertito rispetto al normale
|
||
bool TPag_per_cms_recordset::test_swap(TCausale& caus, bool ritsoc) const
|
||
{
|
||
const char sez = ritsoc ? caus.sezione_ritsoc() : caus.sezione_clifo();
|
||
const bool s = (caus.iva() == iva_vendite) ^ (sez == 'D');
|
||
return s;
|
||
}
|
||
|
||
// Calcola il totale del documento tenendo conto del segno della prima riga e di quella delle
|
||
// ritenute sociali sulla causale
|
||
real TPag_per_cms_recordset::totale_documento(const TRectype& mov) const
|
||
{
|
||
real tot = mov.get_real(MOV_TOTDOC); // Legge totale
|
||
const real ritfis = mov.get_real(MOV_RITFIS);
|
||
tot += ritfis; // Somma ritenute fiscali
|
||
|
||
const real ritsoc = mov.get_real(MOV_RITSOC);
|
||
|
||
if (!ritsoc.is_zero())
|
||
{
|
||
TCausale caus(mov.get(MOV_CODCAUS));
|
||
const bool swapt = test_swap(caus, false); // Totale invertito ?
|
||
const bool swaps = test_swap(caus, true); // Ritenute sociali invertite ?
|
||
if (swapt ^ swaps) // Somma ritenute sociali con segno
|
||
tot -= ritsoc;
|
||
else
|
||
tot += ritsoc;
|
||
}
|
||
|
||
return tot;
|
||
}
|
||
|
||
int TPag_per_cms_recordset::cerca_riga_fattura_origine(const TPartita& match, const TRectype& riga_pag)
|
||
{
|
||
//scansione delle righe partita passata, precedenti alla riga_pag
|
||
const int k = riga_pag.get_int(PART_NRIGA);
|
||
for (int i = match.pred(k); i > 0; i = match.pred(i))
|
||
{
|
||
const TRiga_partite& riga_part = match.riga(i);
|
||
if (riga_part.is_fattura())
|
||
{
|
||
for (int j = riga_part.rate(); j > 0; j--)
|
||
{
|
||
if (match.esiste(i, j, k)) //se esiste il pagamento k della rata j della riga partita i contenente la fattura
|
||
return i;
|
||
}
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
real TPag_per_cms_recordset::calcola_pagato_prec(const TPartita& match, const int riga_fatt, const TRectype& riga_pag)
|
||
{
|
||
real pagato = ZERO;
|
||
if (riga_fatt > 0)
|
||
{
|
||
const int k = riga_pag.get_int(PART_NRIGA);
|
||
const TDate data_rif = riga_pag.get(_campodata); //data di riferimento selezionata sulla maschera
|
||
|
||
const TRiga_partite& riga_part = match.riga(riga_fatt);
|
||
for (int i = riga_part.rate(); i > 0; i--)
|
||
{
|
||
TRiga_scadenze& sc = riga_part.rata(i);
|
||
for (int j = sc.last(); j > 0; j = sc.pred(j))
|
||
{
|
||
const TRiga_partite& pag = match.riga(j);
|
||
const TDate datapag = pag.get_date(_campodata);
|
||
const long cmp = datapag - data_rif;
|
||
//la riga pagamento e' da considerare quando ha data anteriore a quella di riferimento oppur
|
||
//ha data uguale ma numero di registrazione inferiore (insomma, il pagamento e' precedente
|
||
//a quello di riga_pag)
|
||
if (cmp < 0 || (cmp == 0 && j <= k))
|
||
{
|
||
pagato += pag.get_real(PAGSCA_IMPORTO);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return pagato;
|
||
}
|
||
|
||
|
||
/////////////////////////////////////
|
||
// movimenti senza saldaconto
|
||
/////////////////////////////////////
|
||
long TPag_per_cms_recordset::find_movimento(const TRectype& riga_pag) const
|
||
{
|
||
int n_fatture = 0; //numero di fatture trovate
|
||
int first_fatt = 0; //numero riga della prima fattura
|
||
//scan della partita dall'ultima alla prima riga
|
||
const TPartita partita(riga_pag);
|
||
for (int p = partita.last(); p > 0; p = partita.pred(p))
|
||
{
|
||
const TRiga_partite& fatt = partita.riga(p);
|
||
if (fatt.is_fattura())
|
||
{
|
||
n_fatture++;
|
||
first_fatt = p;
|
||
}
|
||
}
|
||
|
||
if (n_fatture > 1)
|
||
{
|
||
const int linea_pag = riga_pag.get_int(PART_NRIGA);
|
||
int linea_fattura = 0;
|
||
for (int f = first_fatt; (f > 0) && (f <= partita.last()) && (linea_fattura == 0); f = partita.succ(f))
|
||
{
|
||
const TRiga_partite& fatt = partita.riga(f);
|
||
if (fatt.is_fattura())
|
||
{
|
||
for (int r = 1; r <= fatt.rate(); r++)
|
||
{
|
||
const TRiga_scadenze& rata = fatt.rata(r);
|
||
if (rata.exist(linea_pag))
|
||
{
|
||
linea_fattura = f;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if (linea_fattura > 0) // oppure anche (linea_fattura > first_fatt)
|
||
first_fatt = linea_fattura;
|
||
}
|
||
|
||
long nreg = 0;
|
||
if (first_fatt > 0)
|
||
{
|
||
const TRiga_partite& fatt = partita.riga(first_fatt);
|
||
nreg = fatt.get_long(PART_NREG);
|
||
}
|
||
|
||
return nreg;
|
||
}
|
||
|
||
//prepara gli oggetti (_righecosti,_righepagamenti) contenenti le righe dei pagamenti..
|
||
//..senza saldaconto
|
||
void TPag_per_cms_recordset::find_commesse_cg(const TRectype& mov)
|
||
{
|
||
const long numregcg = mov.get_long(MOV_NUMREG);
|
||
|
||
//cerca un record di MOVANA che abbia numregcg = nreg;usa il nuovo metodo fighissimo..
|
||
//..con la isam query implementato nella query_movama_by_numregcg()
|
||
TISAM_recordset movana(query_movama_by_numregcg(numregcg));
|
||
const TRecnotype items = movana.items();
|
||
|
||
if (items > 0)
|
||
{
|
||
if (items > 1)
|
||
error_box(TR("Esiste piu' di un movimento analitico collegato al movimento contabile %ld"),numregcg);
|
||
|
||
movana.move_last(); //si posiziona sul record corretto
|
||
//prepara il record tmpcurr sul file temporaneo _tmp su cui registrare i dati da stampare
|
||
TRectype& tmpcurr = _tmp->curr();
|
||
tmpcurr.zero();
|
||
|
||
//crea il movana legato al mov
|
||
const TAnal_mov anal_mov(mov);
|
||
const TRecord_array& anal_rows = anal_mov.body();
|
||
|
||
for (int j = 1; j <= anal_rows.rows(); j++) //scansiona righe analitiche..
|
||
{
|
||
const TRectype& anal_row = anal_rows[j];
|
||
if (check_cms_cdc_fsc(anal_row))
|
||
{
|
||
//prende il conto sulla riga analitica e lo confronta con quelli della configurazione
|
||
const TString& conto_riga_analitica = anal_row.get(RMOVANA_CODCONTO);
|
||
const int gruppo_anal = atoi(conto_riga_analitica.left(3));
|
||
const int conto_anal = atoi(conto_riga_analitica.mid(3,3));
|
||
const long sottoconto_anal = atol(conto_riga_analitica.mid(6,6));
|
||
|
||
const TBill conto(gruppo_anal, conto_anal, sottoconto_anal);
|
||
int tipo = cerca_costo(conto) || cerca_pagamento(conto);
|
||
if (tipo > 0)
|
||
{
|
||
const char sezione = anal_row.get_char(RMOVANA_SEZIONE);
|
||
const real valore = anal_row.get_real(RMOVANA_IMPORTO);
|
||
TImporto imp(sezione, valore);
|
||
|
||
switch (tipo)
|
||
{
|
||
case 1:imp.normalize('D');break;
|
||
case 2:imp.normalize('A');break;
|
||
//case 3:imp.normalize('D');break;
|
||
//case 4:imp.normalize('A');break;
|
||
default:break;
|
||
}
|
||
|
||
//deve aggiungere ora al file temporaneo il record
|
||
//codice fornitore e descrizione
|
||
const long codforn = mov.get_long(MOV_CODCF);
|
||
if (codforn > 0)
|
||
{
|
||
tmpcurr.put("CODFORN", codforn);
|
||
TString16 keyclifo;
|
||
keyclifo.format("F|%ld", codforn);
|
||
const TRectype& rec_clifo = cache().get(LF_CLIFO, keyclifo);
|
||
tmpcurr.put("DESFORN", rec_clifo.get(CLI_RAGSOC));
|
||
}
|
||
|
||
//nreg,data pagamento,descrizione pagamento
|
||
tmpcurr.put("NREG", numregcg);
|
||
tmpcurr.put("DATAREG", mov.get_date(MOV_DATAREG));
|
||
tmpcurr.put("DATAPAG", mov.get_date(MOV_DATACOMP));
|
||
|
||
//documento origine
|
||
tmpcurr.put("NDOC", mov.get_long(MOV_NUMDOC));
|
||
tmpcurr.put("DATADOC", movana.get(MOV_DATADOC).as_date());
|
||
tmpcurr.put("TOTDOC", movana.get(MOV_TOTDOC).as_real());
|
||
|
||
//importi
|
||
tmpcurr.put("TOTPAG", imp.valore());
|
||
//tmpcurr.put("TOTRES", ); //pagamenti precedenti al
|
||
|
||
//campi relativi a cdc,commessa,fase
|
||
tmpcurr.put("CMS",anal_row.get(RMOVANA_CODCMS));
|
||
tmpcurr.put("CDC",anal_row.get(RMOVANA_CODCCOSTO));
|
||
tmpcurr.put("FSC",anal_row.get(RMOVANA_CODFASE));
|
||
|
||
//e finalmente aggiunge il record al file temporaneo
|
||
_tmp->write();
|
||
}
|
||
}
|
||
} //for(j<anal_rows...
|
||
} //if(items>0...
|
||
|
||
}
|
||
|
||
bool TPag_per_cms_recordset::mov_callback(const TRelation& rel, void* pJolly)
|
||
{
|
||
TPag_per_cms_recordset* recordset = (TPag_per_cms_recordset*)pJolly;
|
||
recordset->find_commesse_cg(rel.curr());
|
||
return true;
|
||
}
|
||
|
||
void TPag_per_cms_recordset::scan_movs()
|
||
{
|
||
if (_campodata == PART_DATAPAG) // I movimenti non hanno DATAPAG
|
||
_campodata = MOV_DATAREG;
|
||
|
||
TString filtro = "(REG==\"\")&&(TIPOMOV==\"\")";
|
||
|
||
TRectype darec(LF_MOV), arec(LF_MOV);
|
||
if (_campodata == MOV_DATAREG)
|
||
{
|
||
if (_dadata.ok())
|
||
darec.put(MOV_DATAREG, _dadata);
|
||
if (_adata.ok())
|
||
arec.put(MOV_DATAREG, _adata);
|
||
}
|
||
else
|
||
{
|
||
TString80 f;
|
||
if (_dadata.ok())
|
||
{
|
||
f.format("&&(ANSI(%s)>=\"%s\")", (const char*)_campodata, _dadata.string(ANSI));
|
||
filtro << f;
|
||
}
|
||
if (_adata.ok())
|
||
{
|
||
f.format("&&(ANSI(%s)<=\"%s\")", (const char*)_campodata, _adata.string(ANSI));
|
||
filtro << f;
|
||
}
|
||
}
|
||
|
||
TRelation rel(LF_MOV);
|
||
TCursor cur(&rel, filtro, 2, &darec, &arec);
|
||
cur.scan(mov_callback, this, "Movimenti senza saldaconto...");
|
||
|
||
}
|
||
|
||
bool TPag_per_cms_recordset::check_cms_cdc_fsc(const TRectype& rec_analriga)
|
||
{
|
||
if (_codcosto.not_empty() && _codcosto != rec_analriga.get(RMOVANA_CODCCOSTO))
|
||
return false;
|
||
if (_codcms.not_empty() && _codcms != rec_analriga.get(RMOVANA_CODCMS))
|
||
return false;
|
||
if (_codfas.not_empty() && _codfas != rec_analriga.get(RMOVANA_CODFASE))
|
||
return false;
|
||
if (_contsep.not_empty())
|
||
{
|
||
const TRectype & movana = cache().get(LF_MOVANA, rec_analriga.get_long(RMOVANA_NUMREG));
|
||
|
||
if (_contsep != movana.get(MOVANA_CONTSEP))
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
//////////////////////////////////////
|
||
// movimenti con saldaconto
|
||
//////////////////////////////////////
|
||
const TString& TPag_per_cms_recordset::query_movama_by_numregcg(const long nreg)
|
||
{
|
||
TString& query = get_tmp_string();
|
||
query << "USE MOVANA KEY 3\n";
|
||
query << "FROM NUMREGCG=" << nreg << "\n";
|
||
query << "TO NUMREGCG=" << nreg;
|
||
return query;
|
||
}
|
||
|
||
//prepara l'assoc con tutte le righe da mandare in stampa per quanto riguarda i movimenti con
|
||
//saldaconto (siano essi con o senza iva)
|
||
void TPag_per_cms_recordset::find_commesse(const long nreg, const TRectype& riga_pag)
|
||
{
|
||
//cerca un record di MOVANA che abbia numregcg = nreg;usa il nuovo metodo fighissimo..
|
||
//..con la isam query implementato nella query_movama_by_numregcg()
|
||
TISAM_recordset movana(query_movama_by_numregcg(nreg));
|
||
const TRecnotype items = movana.items();
|
||
if (items <= 0)
|
||
return;
|
||
|
||
if (items > 1)
|
||
warning_box(TR("Esiste piu' di un movimento analitico collegato al movimento contabile %ld"),nreg);
|
||
|
||
movana.move_last(); //si posiziona sul record corretto
|
||
|
||
//crea il movana e le sue righe
|
||
const TAnal_mov anal_mov(movana.get(MOVANA_NUMREG).as_int());
|
||
TRecord_array& anal_rows = anal_mov.body();
|
||
//scandisce le righe del movana alla ricerca di righe compatibili con le commesse sullo sheet
|
||
int m;
|
||
for (m = anal_rows.last_row(); m > 0; m--)
|
||
{
|
||
if (check_cms_cdc_fsc(anal_rows[m]))
|
||
break;
|
||
}
|
||
//se non ne ha trovata manco una di righe buone esce!
|
||
if (m <= 0)
|
||
return;
|
||
|
||
//prepara il record tmpcurr sul file temporaneo _tmp su cui registrare i dati da stampare
|
||
TRectype& tmpcurr = _tmp->curr();
|
||
tmpcurr.zero();
|
||
|
||
//crea un movimento p.n. con il numero reg che viene passato al metodo (nreg relativo..
|
||
//..ad un movimento della fattura originaria)
|
||
TMovimentoPN pn;
|
||
|
||
pn.curr().put(MOV_NUMREG, nreg);
|
||
if (pn.read() == NOERR)
|
||
{
|
||
const TRectype& movfat = pn.curr();
|
||
|
||
real totdoc_cms;
|
||
real totdoc, totdoc_netto;
|
||
TAssoc_array commesse;
|
||
|
||
//Movimenti CON SALDACONTO
|
||
//se movimento IVA..
|
||
if (pn.iva_items() > 0)
|
||
{
|
||
//trova le RMOVANA del MOVANA corrente che hanno il conto = a quello della i-esima rigaiva
|
||
for (int j = 0; j < pn.iva_items(); j++)
|
||
{
|
||
const TRectype& rmoviva = pn.iva(j);
|
||
const TBill zio(rmoviva);
|
||
//il tutto si fa solo se l'indicatore di bilancio del conto nella riga iva e' != 5
|
||
if (zio.indicatore_bilancio() != 5)
|
||
{
|
||
//e vediamo 'sto conto della riga iva..
|
||
const int gruppo_iva = zio.gruppo();
|
||
const int conto_iva = zio.conto();
|
||
const long sottoconto_iva = zio.sottoconto();
|
||
|
||
real imponibile_iva = rmoviva.get_real(RMI_IMPONIBILE);
|
||
real imposta_iva = rmoviva.get_real(RMI_IMPOSTA);
|
||
const TString& tipodet = rmoviva.get(RMI_TIPODET);
|
||
//controlla se l'imposta va sommata (tipo detrazione iva non nulla)
|
||
if (tipodet.full())
|
||
imponibile_iva += imposta_iva;
|
||
|
||
//distributore per il lordo iva (che sara' distribuito successivamente in base..
|
||
//..agli importi delle righe analitiche corretti per le % iva
|
||
TGeneric_distrib agip (imponibile_iva, TCurrency::get_firm_dec());
|
||
|
||
for (int k = 1; k <= anal_rows.rows(); k++) //scansiona righe analitiche..
|
||
{
|
||
real perc_ded_iva = UNO; //%iva deducibile (di default 100, a meno del prorata)
|
||
if (imposta_iva != ZERO)
|
||
{
|
||
//controllo prorata
|
||
const TString80 commessa_riga_anal = anal_rows[k].get(RMOVANA_CODCMS);
|
||
const TRectype& pla = cache().get(LF_COMMESSE, commessa_riga_anal);
|
||
const bool prorata = pla.get_bool("PRORATA");
|
||
if (prorata)
|
||
{
|
||
const TDate datareg = pn.curr().get_date(MOV_DATAREG);
|
||
const int anno = datareg.year();
|
||
TRegistro registro(pn.curr().get(MOV_REG), anno);
|
||
//%deducibilit<69> iva rivista con il prorata
|
||
perc_ded_iva = (CENTO - registro.prorata(anno))/CENTO;
|
||
imposta_iva.round(TCurrency::get_firm_dec()); //ci vanno i decimali della ditta
|
||
}
|
||
} //if imposta_iva...
|
||
|
||
//prende il conto sulla riga analitica e lo confronta con quello della riga iva
|
||
const int gruppo_anal = atoi(anal_rows[k].get(RMOVANA_CODCONTO).left(3));
|
||
const int conto_anal = atoi(anal_rows[k].get(RMOVANA_CODCONTO).mid(3,3));
|
||
const long sottoconto_anal = atol(anal_rows[k].get(RMOVANA_CODCONTO).mid(6,6));
|
||
|
||
//il codconto anale e iva coincidono?..
|
||
if (gruppo_iva == gruppo_anal && conto_iva == conto_anal && sottoconto_iva == sottoconto_anal)
|
||
{
|
||
//..in tal caso aggiunge l'importo della riga analitica al distributore, dopo..
|
||
//..averlo corretto in base alle % precedentemente calcolate
|
||
real importo_anal = anal_rows[k].get_real(RMOVANA_IMPORTO);
|
||
const real perc_iva = imposta_iva / imponibile_iva;
|
||
const real perc_corretta_iva = perc_iva * (UNO - perc_ded_iva);
|
||
importo_anal = importo_anal * (UNO - perc_corretta_iva);
|
||
|
||
agip.add(importo_anal);
|
||
} //if(gruppo_iva==...
|
||
} //for (anal_rows...
|
||
|
||
for (int l = 1; l <= anal_rows.rows(); l++) //..allora le scansiona..
|
||
{
|
||
//prende il conto sulla riga analitica e lo confronta con quello della riga iva
|
||
const int gruppo_anal = atoi(anal_rows[l].get(RMOVANA_CODCONTO).left(3));
|
||
const int conto_anal = atoi(anal_rows[l].get(RMOVANA_CODCONTO).mid(3,3));
|
||
const long sottoconto_anal = atol(anal_rows[l].get(RMOVANA_CODCONTO).mid(6,6));
|
||
|
||
//il codconto anale e iva coincidono?
|
||
if (gruppo_iva == gruppo_anal && conto_iva == conto_anal && sottoconto_iva == sottoconto_anal)
|
||
{
|
||
//impoerto
|
||
real importo = agip.get();
|
||
//commessa,cdc,fase della riga analitica devono essere coincidenti con quelle dello sheet
|
||
if (check_cms_cdc_fsc(anal_rows[l]))
|
||
{
|
||
//costruzione dell'assoc_array 'commesse' con cms/cdc/fsc ed importi
|
||
TToken_string cms_cdc_fsc;
|
||
cms_cdc_fsc.add(anal_rows[l].get(RMOVANA_CODCMS));
|
||
cms_cdc_fsc.add(anal_rows[l].get(RMOVANA_CODCCOSTO));
|
||
cms_cdc_fsc.add(anal_rows[l].get(RMOVANA_CODFASE));
|
||
|
||
real* imp = (real*)commesse.objptr(cms_cdc_fsc);
|
||
//aggiunge un elemento all'assoc_array...
|
||
if (imp == NULL)
|
||
{
|
||
imp = new real;
|
||
commesse.add(cms_cdc_fsc, imp);
|
||
}
|
||
*imp += importo;
|
||
totdoc_cms += importo;
|
||
|
||
} //if check_cms_cdc_fsc...
|
||
|
||
} //if(gruppo_iva==...
|
||
|
||
} //for (anal_rows...
|
||
|
||
} //if indicatore_bilancio!=5...
|
||
|
||
} //for (pn.iva_items(...
|
||
|
||
totdoc = totale_documento(pn.curr()); //tot doc con ritenute fiscali + ritenute sociali (da stampare)
|
||
totdoc_netto = pn.curr().get_real(MOV_TOTDOC); //questo si usa solo per il calcolo del residuo
|
||
} //if(pn.iva_items(...
|
||
else //..movimento NON iva (sempre con saldaconto)
|
||
{
|
||
for (int j = 0; j < pn.cg_items(); j++)
|
||
{
|
||
const TRectype& rmov = pn.cg(j);
|
||
const TBill zio_cg(rmov);
|
||
|
||
TImporto importo(rmov.get_char(RMV_SEZIONE), rmov.get_real(RMV_IMPORTO));
|
||
importo.normalize('D');
|
||
|
||
if (zio_cg.tipo() > ' ')
|
||
{
|
||
totdoc -= importo.valore();
|
||
totdoc_netto -= importo.valore(); //valore per il calcolo del residuo
|
||
}
|
||
else
|
||
if (cerca_fiscali(zio_cg) || cerca_sociali(zio_cg))
|
||
totdoc -= importo.valore(); //valore da stampare nella colonna Tot.fattura con ritenute
|
||
} //for j < pn.cg_items...
|
||
|
||
for (int k = 1; k <= anal_rows.rows(); k++) //..allora le scansiona..
|
||
{
|
||
//prende gr/co/sott sulla riga analitica...
|
||
const int gruppo_anal = atoi(anal_rows[k].get(RMOVANA_CODCONTO).left(3));
|
||
const int conto_anal = atoi(anal_rows[k].get(RMOVANA_CODCONTO).mid(3,3));
|
||
const long sottoconto_anal = atol(anal_rows[k].get(RMOVANA_CODCONTO).mid(6,6));
|
||
//..e crea il conto contabile corrispondente
|
||
TBill conto_cg(gruppo_anal, conto_anal, sottoconto_anal);
|
||
|
||
//l'indicatore di bilancio del conto contabile appena creato e' valido?
|
||
if (conto_cg.indicatore_bilancio() != 5)
|
||
{
|
||
const real importo_anal = anal_rows[k].get_real(RMOVANA_IMPORTO);
|
||
|
||
//costruzione dell'assoc_array 'commesse' con cms/cdc/fsc ed importi
|
||
TToken_string cms_cdc_fsc;
|
||
cms_cdc_fsc.add(anal_rows[k].get(RMOVANA_CODCMS));
|
||
cms_cdc_fsc.add(anal_rows[k].get(RMOVANA_CODCCOSTO));
|
||
cms_cdc_fsc.add(anal_rows[k].get(RMOVANA_CODFASE));
|
||
|
||
real* imp = (real*)commesse.objptr(cms_cdc_fsc);
|
||
|
||
if (imp == NULL)
|
||
{
|
||
imp = new real;
|
||
commesse.add(cms_cdc_fsc, imp);
|
||
}
|
||
|
||
TImporto importo(anal_rows[k].get_char(RMOVANA_SEZIONE), anal_rows[k].get_real(RMOVANA_IMPORTO));
|
||
importo.normalize('D');
|
||
|
||
*imp += importo.valore();
|
||
totdoc_cms += importo.valore();
|
||
} //if(conto_cg.indicatore...
|
||
} //for(k<anal_rows...
|
||
} //else (pn.iva_items(...
|
||
|
||
//parte comune a movimenti IVA e non (vengono anche qui considerate le ritenute fiscali
|
||
//e sociali perche' possono essere state inserite direttamente nella partita e non nel movimento
|
||
//(quindi non si puo' in questo caso applicare la totale_documento()
|
||
//Le ritenute fiscali vanno sempre sommate..
|
||
real totpagato = riga_pag.get_real(PART_IMPORTO) + riga_pag.get_real(PART_RITENUTE);
|
||
//Le ritenute sociali invece vanno testate con la test_swap..
|
||
const real ritsoc = riga_pag.get_real(PART_RITSOC);
|
||
if (!ritsoc.is_zero())
|
||
{
|
||
const TRectype& mov = pn.curr();
|
||
TCausale caus(mov.get(MOV_CODCAUS));
|
||
const bool swapt = test_swap(caus, false); // Totale invertito ?
|
||
const bool swaps = test_swap(caus, true); // Ritenute sociali invertite ?
|
||
if (swapt ^ swaps) // Somma ritenute sociali con segno
|
||
totpagato -= ritsoc;
|
||
else
|
||
totpagato += ritsoc;
|
||
}
|
||
|
||
const real percentuale = totpagato / totdoc_netto;
|
||
|
||
//calcolo del residuo (solo movimenti saldacontati)
|
||
//mi servono,dalla riga partita che viene passata,i valori dei campi per la chiave del
|
||
//file delle scadenze
|
||
const TPartita match(riga_pag);
|
||
//ci serve la riga di fattura che origina la nostra riga pagamento
|
||
const int riga_fatt = cerca_riga_fattura_origine(match, riga_pag);
|
||
//quanto era stato pagato del documento prima della attuale riga_pag
|
||
const real totpagato_prec = calcola_pagato_prec(match, riga_fatt, riga_pag);
|
||
const real perc_prec = totpagato_prec / totdoc_netto;
|
||
|
||
TGeneric_distrib distributore(totdoc_cms * percentuale, TCurrency::get_firm_dec());
|
||
TGeneric_distrib distributore_prec(totdoc_cms * perc_prec, TCurrency::get_firm_dec());
|
||
{
|
||
FOR_EACH_ASSOC_OBJECT(commesse, h, k, imp)
|
||
{
|
||
const real& impcms = *(real*)imp;
|
||
distributore.add(impcms);
|
||
distributore_prec.add(impcms); //distributore di importo pagato sulle commesse
|
||
}
|
||
}
|
||
|
||
FOR_EACH_ASSOC_OBJECT(commesse, h, k, imp)
|
||
{
|
||
const real& impcms = *(real*)imp;
|
||
|
||
// campi del pagamento che vanno spediti nel file temporaneo
|
||
//codice fornitore e descrizione
|
||
const long codforn = riga_pag.get_long(PART_SOTTOCONTO);
|
||
tmpcurr.put("CODFORN", codforn);
|
||
TString16 keyclifo;
|
||
keyclifo.format("F|%ld", codforn);
|
||
const TRectype& rec_clifo = cache().get(LF_CLIFO, keyclifo);
|
||
tmpcurr.put("DESFORN", rec_clifo.get(CLI_RAGSOC));
|
||
|
||
//nreg,data pagamento,descrizione pagamento
|
||
tmpcurr.put("NREG", nreg);
|
||
tmpcurr.put("DATAPAG", riga_pag.get_date(PART_DATAPAG));
|
||
tmpcurr.put("DATAREG", riga_pag.get_date(PART_DATAREG));
|
||
tmpcurr.put("DESCRPAG", riga_pag.get(PART_DESCR));
|
||
|
||
//documento origine
|
||
tmpcurr.put("NDOC", movfat.get_long(MOV_NUMDOC));
|
||
tmpcurr.put("DATADOC", movfat.get_date(MOV_DATADOC));
|
||
tmpcurr.put("PROT", movfat.get_long(MOV_PROTIVA));
|
||
tmpcurr.put("TOTDOC", totdoc);
|
||
tmpcurr.put("TOTPAG", distributore.get()); //pagamento nella partita
|
||
//totres = importo da pagare (sulla fattura) - pagamenti precedenti al
|
||
tmpcurr.put("TOTRES", impcms - distributore_prec.get());
|
||
|
||
//campi relativi a cdc,commessa,fase
|
||
TToken_string cdc_cms_fsc = k;
|
||
tmpcurr.put("CMS",cdc_cms_fsc.get(0));
|
||
tmpcurr.put("CDC",cdc_cms_fsc.get(1));
|
||
tmpcurr.put("FSC",cdc_cms_fsc.get(2));
|
||
|
||
//e finalmente aggiunge il record al file temporaneo
|
||
_tmp->write();
|
||
} //FOR_EACH_...
|
||
|
||
} //pn.read()...
|
||
|
||
}
|
||
|
||
bool TPag_per_cms_recordset::part_callback(const TRelation& rel, void* pJolly)
|
||
{
|
||
TPag_per_cms_recordset* recordset = (TPag_per_cms_recordset*)pJolly;
|
||
const TRectype& riga_part_pag = rel.curr();
|
||
|
||
const long nreg = recordset->find_movimento(riga_part_pag); //prima cerco un movimento della fattura...
|
||
if (nreg > 0) //..se ne trovo almeno uno cerco la commessa corrispondente
|
||
recordset->find_commesse(nreg, riga_part_pag);
|
||
return true;
|
||
}
|
||
|
||
void TPag_per_cms_recordset::scan_pags()
|
||
{
|
||
//costruzione filtro
|
||
TRectype dafiltrec(LF_PARTITE);
|
||
dafiltrec.put(PART_TIPOCF, 'F');
|
||
dafiltrec.put(PART_GRUPPO, 0);
|
||
dafiltrec.put(PART_CONTO, 0);
|
||
dafiltrec.put(PART_SOTTOCONTO, _dacodfor);
|
||
|
||
TRectype afiltrec(dafiltrec);
|
||
afiltrec.put(PART_SOTTOCONTO, _acodfor);
|
||
|
||
TString filtro = "(TIPOMOV>=\"3\")"; //deve essere un pagamento a fornitore!!!
|
||
|
||
if (_dadata.ok())
|
||
{
|
||
TString80 f;
|
||
f.format("&&(ANSI(%s)>=\"%s\")", (const char*)_campodata, _dadata.string(ANSI));
|
||
filtro << f;
|
||
}
|
||
if (_adata.ok())
|
||
{
|
||
TString80 f;
|
||
f.format("&&(ANSI(%s)<=\"%s\")", (const char*)_campodata, _adata.string(ANSI));
|
||
filtro << f;
|
||
}
|
||
//applica il filtro alla relazione
|
||
TRelation rel(LF_PARTITE);
|
||
TCursor cur(&rel, filtro, 1, &dafiltrec, &afiltrec);
|
||
cur.scan(part_callback, this, "Movimenti con saldaconto...");
|
||
}
|
||
|
||
void TPag_per_cms_recordset::set_filter(const TPag_per_cms_mask& msk, const int cms_row, const long dacodfor, const long acodfor, const TString& campodata)
|
||
{
|
||
//se esiste il file temporano con tracciato persomalizzato lo cancella e lo ricrea vuoto
|
||
TFilename trr; //file tracciato record
|
||
trr.tempdir();
|
||
trr.add("paid");
|
||
TFilename dbf(trr); //file dati
|
||
|
||
trr.ext("trr");
|
||
dbf.ext("dbf");
|
||
|
||
//scelta tipo data di estrazione (registrazione, documento, pagamento)
|
||
//deve stare qui per poter generare la chiave del file temporaneo in base al tipo di data di estrazione
|
||
_campodata = campodata;
|
||
//stessa cosa per il simpatico codice fornitore
|
||
_dacodfor = dacodfor;
|
||
_acodfor = acodfor;
|
||
|
||
//crea il file .trr in base ai parametri del metodo
|
||
crea_trr(trr);
|
||
//svuota la memoria dal vecchio file temporaneo
|
||
if (_tmp != nullptr)
|
||
delete _tmp;
|
||
|
||
//crea in memoria il nuovo file temporaneo e lo azzera (non si sa mai..)
|
||
_tmp = new TExternisamfile(dbf, trr);
|
||
_tmp->zap();
|
||
|
||
//prende un po' di dati dalla maschera
|
||
_codcosto = _codcms = _codfas = "";
|
||
if (cms_row >= 0)
|
||
{
|
||
TSheet_field& sf = msk.sfield(F_RIGHE);
|
||
TMask& sm = sf.sheet_mask(); //metodo ingannatore per ottenere tutti i campi dallo sheet..
|
||
sf.update_mask(cms_row); //..delle cms/fsc/cdc senza rifare il giro della configurazione..
|
||
TRelation rel(LF_RMOVANA); //..anale
|
||
sm.autosave(rel);
|
||
_codcosto = rel.curr().get(RMOVANA_CODCCOSTO);
|
||
_codcms = rel.curr().get(RMOVANA_CODCMS);
|
||
_codfas = rel.curr().get(RMOVANA_CODFASE);
|
||
}
|
||
|
||
//lettura eventuali date limite (il controllo sul loro valore sara' nei metodi di costruzione
|
||
//dei filtri
|
||
_dadata = msk.get_date(F_DATAINI);
|
||
_adata = msk.get_date(F_DATAFIN);
|
||
|
||
_contsep = msk.get(F_CONTSEP);
|
||
|
||
//carica i conti memorizzati nel ca3600.ini,registrandoli negli assoc_array _costi ecc...
|
||
lettura_conti(_costi, 'C');
|
||
lettura_conti(_pagamenti, 'P');
|
||
lettura_conti(_fiscali, 'F');
|
||
lettura_conti(_sociali, 'S');
|
||
|
||
//scansione movimenti con saldaconto
|
||
scan_pags();
|
||
|
||
//se c'e' un filtro sui fornitori, non si fa lo scan dei movimenti senza saldaconto
|
||
if (dacodfor <= 0 && acodfor <= 0)
|
||
scan_movs();
|
||
}
|
||
|
||
////////////////////////////////////////////////////////
|
||
// REPORT
|
||
////////////////////////////////////////////////////////
|
||
class TPag_per_cms_rep : public TAnal_report
|
||
{
|
||
|
||
protected:
|
||
virtual bool set_recordset(const TString& sql);
|
||
virtual bool get_usr_val(const TString& name, TVariant& var) const;
|
||
virtual void set_dbase_fixed_fields(bool on = true);
|
||
|
||
public:
|
||
void set_filter(const TPag_per_cms_mask& msk, const int cms_row, const long dacodfor, const long acodfor, const TString& campodata);
|
||
};
|
||
|
||
|
||
bool TPag_per_cms_rep::get_usr_val(const TString& name, TVariant& var) const
|
||
{
|
||
return TAnal_report::get_usr_val(name, var);
|
||
}
|
||
|
||
void TPag_per_cms_rep::set_dbase_fixed_fields(bool on)
|
||
{
|
||
field("B1.201")->show(on);
|
||
field("B1.202")->show(on);
|
||
field("B1.203")->show(on);
|
||
field("B1.204")->show(on);
|
||
}
|
||
|
||
bool TPag_per_cms_rep::set_recordset(const TString& sql)
|
||
{
|
||
TPag_per_cms_recordset* rs = new TPag_per_cms_recordset(sql);
|
||
return TAnal_report::set_recordset(rs);
|
||
}
|
||
|
||
|
||
void TPag_per_cms_rep::set_filter(const TPag_per_cms_mask& msk, const int cms_row, const long dacodfor, const long acodfor, const TString& campodata)
|
||
{
|
||
TAnal_report::set_recordset(NULL);
|
||
|
||
const char* query ="USE 1000"; //\nJOIN MOVANA INTO NUMREG==NUMRD\nJOIN RMOVANA INTO NUMREG==NUMRD NUMRIG==NRIGA";
|
||
|
||
TPag_per_cms_recordset* recset = new TPag_per_cms_recordset(query);
|
||
|
||
recset->set_filter(msk, cms_row, dacodfor, acodfor, campodata);
|
||
TAnal_report::set_recordset(recset);
|
||
}
|
||
|
||
|
||
//===============================================================================================
|
||
////////////////////////////////////////////////////////
|
||
// APPLICAZIONE
|
||
////////////////////////////////////////////////////////
|
||
|
||
class TPag_per_cms : public TReport_application
|
||
{
|
||
TPag_per_cms_mask* _mask;
|
||
TPag_per_cms_rep * _rep;
|
||
|
||
protected:
|
||
virtual TReport & get_report(const TAutomask & m);
|
||
virtual TTrec * get_dbase_recdesc(TReport & rep, const TAutomask & mask);
|
||
virtual TAutomask & get_mask();
|
||
virtual void execute_print(TReport_book & book, TAutomask & mask, TReport & rep, export_type type = _export_printer);
|
||
virtual const char * output_name(const TAutomask & mask, const TReport & rep) const { return "pagcms"; }
|
||
// @cmember Distruzione dei dati dell'utente
|
||
virtual bool user_destroy();
|
||
|
||
public:
|
||
void stampa_per_commessa(const TPag_per_cms_mask& mask, TReport_book& book,
|
||
TPag_per_cms_rep& rep, const long dacodfor, const long acodfor,
|
||
const TString& campodata);
|
||
const TMultilevel_code_info& get_level_one() const;
|
||
|
||
TPag_per_cms() : _mask(nullptr), _rep(nullptr) {}
|
||
~TPag_per_cms() {}
|
||
|
||
};
|
||
|
||
TReport & TPag_per_cms::get_report(const TAutomask & m)
|
||
{
|
||
if (_rep == nullptr)
|
||
_rep = new TPag_per_cms_rep;
|
||
_rep->load(_mask->get(DLG_REPORT));
|
||
return *_rep;
|
||
}
|
||
|
||
TAutomask & TPag_per_cms::get_mask()
|
||
{
|
||
if (_mask == nullptr)
|
||
_mask = new TPag_per_cms_mask;
|
||
return *_mask;
|
||
}
|
||
|
||
TTrec * TPag_per_cms::get_dbase_recdesc(TReport & rep, const TAutomask & mask)
|
||
{
|
||
TTrec * desc = new TTrec;
|
||
TToken_string def;
|
||
TRectype cms(LF_COMMESSE);
|
||
TRectype fasi(LF_FASI);
|
||
TRectype cdc(LF_CDC);
|
||
TRectype rmovana(LF_RMOVANA);
|
||
TRectype movana(LF_MOVANA);
|
||
|
||
desc->add_fielddef(movana.rec_des(), MOVANA_NUMREG);
|
||
desc->add_fielddef(movana.rec_des(), MOVANA_DATAREG);
|
||
desc->add_fielddef(movana.rec_des(), MOVANA_DATAREG);
|
||
desc->set_name("DATAPAG");
|
||
desc->add_fielddef(movana.rec_des(), MOVANA_DESCR);
|
||
desc->add_fielddef(movana.rec_des(), MOVANA_NUMDOC);
|
||
desc->add_fielddef(movana.rec_des(), MOVANA_DATADOC);
|
||
desc->add_fielddef("PROT", _longfld, 6);
|
||
desc->add_fielddef("TOTDOC", _realfld, 18, 2);
|
||
desc->add_fielddef("TOTPAG", _realfld, 18, 2);
|
||
desc->add_fielddef(cdc.rec_des(), CDC_CODCOSTO);
|
||
desc->add_fielddef(cms.rec_des(), COMMESSE_CODCMS);
|
||
desc->add_fielddef(fasi.rec_des(), FASI_CODFASE);
|
||
desc->add_fielddef(movana.rec_des(), MOVANA_CONTSEP);
|
||
|
||
TToken_string keydef(CDC_CODCOSTO, '+');
|
||
|
||
keydef.add(COMMESSE_CODCMS);
|
||
keydef.add(FASI_CODFASE);
|
||
keydef.add(MOVANA_NUMREG);
|
||
|
||
desc->add_keydef(keydef, true);
|
||
|
||
return desc;
|
||
}
|
||
|
||
//metodo per accattarsi o' primo livello della configurazione CA
|
||
const TMultilevel_code_info& TPag_per_cms::get_level_one() const
|
||
{
|
||
TConfig& cfg = ca_config();
|
||
const TString& first_lev = cfg.get("Level(1)");
|
||
const int logic = first_lev == "CDC" ? LF_CDC : LF_COMMESSE;
|
||
|
||
return ca_multilevel_code_info(logic);
|
||
}
|
||
|
||
void TPag_per_cms::stampa_per_commessa(const TPag_per_cms_mask& mask, TReport_book& book, TPag_per_cms_rep& rep,
|
||
const long dacodfor, const long acodfor,
|
||
const TString& campodata)
|
||
{
|
||
TSheet_field& sheet = mask.sfield(F_RIGHE);
|
||
TString video_string; //stringa che compare nella progind
|
||
|
||
if (sheet.empty()) //se non ci sono righe sullo sheet (selezione su tutte le cms/cdc)...
|
||
{
|
||
TToken_string& row = sheet.row(-1); //crea la prima riga dello sheet
|
||
|
||
const TMultilevel_code_info& liv1 = get_level_one(); //stabilisce quale <20> il primo livello (tra CDC e CMS)..
|
||
TISAM_recordset set(liv1.logic() == LF_CDC ? "USE CDC" : "USE COMMESSE"); //..e di conseguenza scrive la use giusta
|
||
TProgress_monitor pi(set.items(), video_string, true);
|
||
|
||
for (int i = 0; pi.add_status() && set.move_to(i); i++) //fighissimo metodo per scandire un file in 1 riga!
|
||
{
|
||
row = set.get((unsigned int)0).as_string(); //prende il valore del primo campo del file (CDC o CMS code)
|
||
video_string = TR("Scansione");
|
||
video_string << " " << row; //completa la stringa da visualizzare sulla progind
|
||
pi.set_text(video_string);
|
||
|
||
for (int l = liv1.levels()-2; l >= 0; l--) //se la struttura <20> a pi<70> livelli costruisce la tokenstring
|
||
row.insert("|", liv1.total_len(l));
|
||
|
||
rep.set_filter(mask, 0, dacodfor, acodfor, campodata); //fa la set filter sulla prima riga (che <20> quella usata)
|
||
book.add(rep);
|
||
}
|
||
sheet.destroy(); //cancella le commesse aggiunte in automatico sullo sheet
|
||
}
|
||
else //se ha almeno una riga sullo sheet delle cms/cdc...
|
||
{
|
||
FOR_EACH_SHEET_ROW(sheet, r, row) //per ogni cdc/cms che appare nello sheet di pag.1 della msk..
|
||
{
|
||
rep.set_filter(mask, r, dacodfor, acodfor, campodata); //..chiama il metodone globale che crea e compila il file..
|
||
//..temporaneo i cui dati riempiranno il report
|
||
book.add(rep); //aggiunge il report relativo alla cdc/cms corrente al book
|
||
}
|
||
}
|
||
}
|
||
|
||
void TPag_per_cms::execute_print(TReport_book & book, TAutomask & mask, TReport & rep, export_type type)
|
||
{
|
||
//il programma si puo' usare SOLO se in contabilita' analitica si usa il piano dei conti contabile
|
||
TConfig& cfg = ca_config();
|
||
const bool use_pdcc = cfg.get_bool("UsePdcc");
|
||
if (!use_pdcc)
|
||
{
|
||
error_box(TR("Programma funzionante SOLO se in contabilita' analitica si usa il piano dei conti contabile"));
|
||
return;
|
||
}
|
||
|
||
//scelta tipo data di estrazione (registrazione, documento, pagamento)
|
||
//viene presa qui perche' serve subito alla set_filter del report prima che venga..
|
||
//..utilizzata nel recordset
|
||
TString16 campodata = PART_DATAREG;
|
||
|
||
switch(_mask->get_int(F_TIPODATA))
|
||
{
|
||
case 1: campodata = PART_DATADOC; break;
|
||
case 2: campodata = PART_DATAPAG; break;
|
||
default: break;
|
||
}
|
||
|
||
//scansione su tutti i fornitori selezionati; questa opzione e' praticamente utile solo..
|
||
//..quando il numero di fornitori selezionati non e' elevato;infatti,per ogni fornitore..
|
||
//..selezionato, viene eseguito tutto il giro del programma
|
||
const long dacodfor = _mask->get_long(F_DACODFOR);
|
||
const long acodfor = _mask->get_long(F_ACODFOR);
|
||
|
||
rep.set_export_sections(type);
|
||
stampa_per_commessa(*_mask, book, (TPag_per_cms_rep &) rep, dacodfor, acodfor, campodata); //se non si specifica alcun clifo...
|
||
rep.reset_export_sections();
|
||
}
|
||
|
||
bool TPag_per_cms::user_destroy()
|
||
{
|
||
safe_delete(_mask);
|
||
safe_delete(_rep);
|
||
return TReport_application::user_destroy();
|
||
}
|
||
|
||
int ca3600(int argc, char* argv[])
|
||
{
|
||
TPag_per_cms a;
|
||
a.run(argc,argv,TR("Stampa pagato per commessa"));
|
||
return 0;
|
||
}
|