campo-sirio/cg/cg7200.cpp

574 lines
16 KiB
C++
Raw Normal View History

#include <applicat.h>
#include <assoc.h>
#include <automask.h>
#include <currency.h>
#include <filetext.h>
#include <msksheet.h>
#include <printer.h>
#include <recarray.h>
#include <relation.h>
#include <sort.h>
#include <utility.h>
#include "cg7.h"
#include "cg7200a.h"
#include "cglib01.h"
#include <mov.h>
#include <rmov.h>
#include <rmoviva.h>
#include <pagsca.h>
#include <partite.h>
#include "../ca/calib01.h"
#include "../ca/movana.h"
#include "../ca/rmovana.h"
#define ALIAS_PCON1 100
#define ALIAS_PCON2 200
#define ALIAS_ABPCON1 300
#define ALIAS_ABPCON2 400
class TInvioP_file: public TFile_text
{
protected:
virtual void validate(TCursor& cur,TRecord_text &rec, TToken_string &val, TString& str);
public:
TInvioP_file(const TString& file_name);
virtual ~TInvioP_file() { }
};
TInvioP_file::TInvioP_file(const TString& file_name)
: TFile_text(file_name, "proforma.ini")
{
}
class TInvioP_mask : public TAutomask
{
protected:
bool on_field_event(TOperable_field& o, TField_event e, long jolly);
public:
TInvioP_mask();
virtual ~TInvioP_mask(){};
};
TInvioP_mask::TInvioP_mask() :TAutomask ("cg7200a")
{
}
bool TInvioP_mask::on_field_event(TOperable_field& o, TField_event e, long jolly)
{
switch (o.dlg())
{
case F_CODDITTA:
if (e==fe_init && o.empty())
{
set(F_CODDITTA, main_app().get_firm());
((TEdit_field&) o).check();
disable(F_CODDITTA);
}
break;
default:
break;
}
return TRUE;
}
class TInvioP : public TSkeleton_application
{
TCursor* _cur;
TInvioP_mask* _msk;
TDate _dataini, _datafin;
long _nregcosto, _nregpag;
real _importo;
TConfig* _configfile;
protected:
virtual bool create(void);
virtual bool destroy(void);
virtual void main_loop() ;
void invio_proforma();
bool i_proforma_movimenti();
bool i_proforma_righe(TCursor& cur, TInvioP_file* trasfile);
bool i_proforma_pagamenti();
bool i_proforma_clifor(char tipocf = 'C');
bool i_proforma_conti();
public:
const real get_importo() {return _importo;};
const char* get_nregcosto() {return format("%d", _nregcosto);};
const char* get_nregpag() {return format("%d", _nregpag);};
TInvioP_file* apri_file(const char* nome);
void chiudi_file(TInvioP_file* trasfile);
TInvioP() {};
virtual ~TInvioP() {};
};
// restituisce un riferimento all' applicazione
inline TInvioP& app() { return (TInvioP&) main_app();}
// gestione dei messaggi estesi nei campi
void TInvioP_file::validate(TCursor& cur,TRecord_text &rec, TToken_string &s, TString& str)
{
const TString code(s.get(0));
TString valore;
if (code == "_FISSO")
{
// gestione dei campi fissi per i record delle riba
// sintassi: _FISSO,!<valore>
// dove: <valore> <20> la stringa fissa da emettere
TString in(s.get());
CHECK(in[0]=='!',"Macro _FISSO senza carattere '!'");
in.ltrim(1);
in.trim();
valore = in;
}
else if (code == "_TELEFONO")
{
valore = str;
valore.trim();
str = cur.curr().get("PTEL");
valore << str;
valore.trim();
}
else if (code == "_CODCBL")
{
valore = str;
int i = valore.find("$");
valore = valore.left(i);
}
else if (code == "_RAGSOC")
{
valore = str;
valore = valore.strip_double_spaces();
}
else if (code == "_FLAG")
{
const char chiusa = str[0];
valore = (chiusa=='X') ? "S" : "A";
}
else if (code == "_NREGCOSTO")
{
valore = app().get_nregcosto();
}
else if (code == "_NREGPAG")
{
valore = app().get_nregpag();
}
else if (code == "_IMPORTO")
{
valore = app().get_importo().string();
}
else NFCHECK("Macro non definita: %s", (const char *)code);
str = valore;
}
TInvioP_file* TInvioP::apri_file(const char* nome)
{
TFilename filename = _msk->get(F_DESTINAZIONE);
filename.add(nome);
filename.ext("txt");
if (filename.exist())
remove(filename);
TInvioP_file* trasfile = new TInvioP_file(filename);
trasfile->open(filename,'w');
trasfile->force_record_separator();
return trasfile;
}
void TInvioP::chiudi_file(TInvioP_file* trasfile)
{
trasfile->close();
delete trasfile;
}
bool TInvioP::i_proforma_conti()
{
TInvioP_file* trasfile = apri_file("pianocon");
TRelation rel(LF_PCON);
TCursor cur(&rel);
const long cur_items = cur.items();
if (cur_items != 0)
{
cur.freeze();
TRectype& cur_rec = cur.curr();
for (cur = 0; cur.pos() < cur_items; ++(cur))
{
TRecord_text rec;
rec.set_type("P");
trasfile->autoload(rec, cur);
trasfile->write(rec);
}
}
chiudi_file(trasfile);
return true;
}
bool TInvioP::i_proforma_movimenti()
{
TInvioP_file* trasfile = apri_file("registra"); //file testate
TInvioP_file* trasfilerighe = apri_file("righe"); //file righe movimenti
//trasferimento testate movimenti (cerca direttamente sui movimenti analitici in chiave 2..
//..,cio<69> per DATACOMP e con NUMREGCG!=0
TRectype da(LF_MOVANA);
TRectype a(LF_MOVANA);
da.put(MOVANA_DATACOMP, _dataini);
a.put(MOV_DATACOMP, _datafin);
TRelation rel(LF_MOVANA);
rel.add(LF_MOV, "NUMREG==NUMREGCG");
rel.add(LF_CAUSALI, "CODCAUS==CODCAUS");
rel.add(LF_RMOVANA, "NUMREG==NUMREG");
rel.add(LF_RMOVIVA, "NUMREG==NUMREGCG");
TCursor cur(&rel, "NUMREGCG!=0", 2, &da, &a);
const long cur_items = cur.items();
if (cur_items != 0)
{
//prepara i record di tipo testata da scrivere
TRecord_text rec;
rec.set_type("T");
cur.freeze();
const TRectype& cur_rec = cur.curr();
for (cur = 0; cur.pos() < cur_items; ++(cur))
{
//carica e scrive il record di testata in base alle informazioni contenute nel proforma.ini
trasfile->autoload(rec, cur);
trasfile->write(rec);
//trasferisce le righe del movimento analitico corrente solo
i_proforma_righe(cur, trasfilerighe);
}
}
chiudi_file(trasfilerighe);
chiudi_file(trasfile);
return true;
}
bool TInvioP::i_proforma_righe(TCursor& cur, TInvioP_file* trasfilerighe)
{
//---- righe movimenti analitica ----
//necessita del numreg del corrente movimento analitico per poterlo istanziare e prenderne le righe
const long numreg = cur.curr().get_long(MOVANA_NUMREG);
TAnal_mov analmov(numreg); //..istanzia il movimento analitico cercato..
TRecord_text recrighe; //istanzia il tipo record corretto da scrivere sul trasfilerighe
recrighe.set_type("R");
int i;
for (i = 1; i <= analmov.body().rows(); i++)
{
//..e scandisce le righe alla ricerca di quelle con conto = gruppo/conto/sottoconto del movimento contabile
const TRectype& riga = analmov.body().row(i);
//inganno il cursore passandogli la riga analitica in esame
cur.curr(LF_RMOVANA) = riga;
trasfilerighe->autoload(recrighe, cur);
trasfilerighe->write(recrighe);
}
//---- righe iva ----
//adesso tocca alle righe iva...e sara' un casino indicibile!
const TString8 numregcg = analmov.get(MOVANA_NUMREGCG);
//record_array con le righe iva aventi il numreg = numregcg analitico
TRecord_array righeiva(numregcg, LF_RMOVIVA);
//assoc array contenente tutti i diversi conti che incontrera' nello scanning delle righe iva
TAssoc_array conti;
//scanning delle righe iva alla ricerca dei conti che compaiono
for (int j = 1; j <= righeiva.rows(); j++)
{
//prende il conto e lo mette nell'assoc_array dei conti (notare che, essendo un assoc_array,..
//..non vengono inseriti doppioni! mitico!!)
TBill conto;
conto.get(righeiva[j]);
const char* codconto = conto.string(8);
//ad ogni conto lega un assoc_array (codivae) che conterra' tutti i codici iva legati a quel..
//..conto nelle righe iva con i relativi importi
TAssoc_array* codivae = (TAssoc_array*) conti.objptr(codconto);
if (codivae == NULL) //se non esiste l'assoc_array legato al conto lo crea
{
codivae = new TAssoc_array;
//aggiunge all'assoc_array conti il suo elemento assoc_array codivae..ho un assoc_array..
//..di assoc_array!
conti.add(codconto, codivae);
}
TString16 codiva = righeiva[j].get(RMI_CODIVA); //prende il codice iva dalla riga iva
//aggiungere qui eventuale codice intero di indetraibilita'
//ad ogni codiva presente in codivae lega un importo che risultera' la somma di tutti gli..
//..importi con lo stesso conto e codice iva
real* tot_imp = (real*) codivae->objptr(codiva);
if (tot_imp == NULL) //se non esiste l'importo legato al codice iva lo crea
{
tot_imp = new real;
//aggiunge all'assoc_array codivae il suo elemento real tot_imp
codivae->add(codiva, tot_imp);
}
//accresce l'importo tot_imp relativo alla coppia codiva+codconto corrente
*tot_imp += righeiva[j].get_real(RMI_IMPONIBILE);
//aggiungere qui eventuale imposta
}
TRecord_text recrigheiva; //istanzia il tipo record corretto da scrivere sul trasfilerighe
recrigheiva.set_type("I");
int nrighe = 0;
for (i = 1; i <= analmov.body().rows(); i++)
{
//scanning delle righe analitiche per estrarne i conti e controllare se compaiono nell'assoc_array..
//..dei conti riempito con i conti trovati nelle righe iva
const TRectype& riga = analmov.body().row(i);
const TString& codconto = riga.get(RMOVANA_CODCONTO);
TAssoc_array* codivae = (TAssoc_array*) conti.objptr(codconto); //assoc_array codivae del codconto
//se ha almeno un codice iva associato a questo conto nell'assoc_array dei conti..
if (codivae != NULL)
{
//..prende l'importo della riga analitica..
real importo_riga = riga.get_real(RMOVANA_IMPORTO);
//..lo ridistribuisce secondo le percentuali iva
TGeneric_distrib distributore(importo_riga, TCurrency::get_firm_dec());
{
FOR_EACH_ASSOC_OBJECT((*codivae), h, k, imp)
{
const real& imp_iva = *(real*)imp;
distributore.add(imp_iva);
}
//crea una riga iva dal cursore, con numreg = numregcg della testata analitica originale
TRectype& rigaiva = cur.curr(LF_RMOVIVA);
rigaiva.put(RMI_NUMREG, numregcg);
//scan dell'assoc_array ridistribuito e inserimento dei valori nella riga iva appena creata
FOR_EACH_ASSOC_OBJECT((*codivae), hi, ki, impi)
{
rigaiva.put(RMI_NUMRIG, ++nrighe);
rigaiva.put(RMI_GRUPPO, codconto.mid(0,3));
rigaiva.put(RMI_CONTO, codconto.mid(3,3));
rigaiva.put(RMI_SOTTOCONTO, codconto.mid(6,6));
TBill zio(rigaiva);
rigaiva.put(RMI_TIPOC, zio.tipo());
rigaiva.put(RMI_IMPONIBILE, distributore.get());
rigaiva.put(RMI_CODIVA, ki);
//scrittura delle righe di tipo I; notare che il cur passato alla autoload altri non e'..
//..che la rigaiva appena completata
trasfilerighe->autoload(recrigheiva, cur);
trasfilerighe->write(recrigheiva);
}
}
}
}
return true;
}
bool TInvioP::i_proforma_pagamenti()
{
TInvioP_file* trasfilepag = apri_file("pagament");
TRectype da(LF_MOVANA);
TRectype a(LF_MOVANA);
da.put(MOVANA_DATACOMP, _dataini);
a.put(MOV_DATACOMP, _datafin);
TRelation rel(LF_MOVANA);
rel.add(LF_MOV, "NUMREG==NUMREGCG");
rel.add(LF_CAUSALI, "CODCAUS==CODCAUS");
TCursor cur(&rel, "NUMREGCG!=0", 2, &da, &a);
const long cur_items = cur.items();
if (cur_items != 0)
{
cur.freeze();
TRectype& cur_rec = cur.curr();
for (cur = 0; cur.pos() < cur_items; ++(cur))
{
// const char tipomov = cur_rec.get(MOVANA_TIPOMOV)[0];
// if (tipomov == '3' || tipomov == '2' || tipomov == '6')
// {
TRelation relpart(LF_PARTITE);
TRectype da(LF_PARTITE);
da.put(PART_NREG, cur.curr().get(MOV_NUMREG));
TCursor curpart(&relpart, "", 2, &da, &da);
const long curpart_items = curpart.items();
if (curpart_items != 0)
{
curpart.freeze();
TRectype& curpart_rec = curpart.curr();
for (curpart = 0; curpart.pos() < curpart_items; ++(curpart))
{
TRelation relpag(LF_PAGSCA);
TRectype da(LF_PAGSCA);
da.put(PAGSCA_TIPOC, curpart_rec.get(PART_TIPOCF));
da.put(PAGSCA_GRUPPO, curpart_rec.get(PART_GRUPPO));
da.put(PAGSCA_CONTO, curpart_rec.get(PART_CONTO));
da.put(PAGSCA_SOTTOCONTO, curpart_rec.get(PART_SOTTOCONTO));
da.put(PAGSCA_ANNO, curpart_rec.get(PART_ANNO));
da.put(PAGSCA_NUMPART, curpart_rec.get(PART_NUMPART));
const int nrigapart = curpart_rec.get_int(PART_NRIGA);
TString80 filtro;
filtro.format("NRIGP == %d", nrigapart);
TCursor curpag(&relpag, filtro, 1, &da, &da);
const long curpag_items = curpag.items();
if (curpag_items != 0)
{
TAssoc_array pagame;
pagame.destroy();
curpag.freeze();
TRectype& curpag_rec = curpag.curr();
for (curpag = 0; curpag.pos() < curpag_items; ++(curpag))
{
TString80 indice = curpag_rec.get(PAGSCA_ANNO);
indice << '|' << curpag_rec.get(PAGSCA_NUMPART);
indice << '|' << curpag_rec.get(PAGSCA_NRIGA);
real importo = ZERO;
bool is_key = pagame.is_key(indice);
real& somma = is_key ? (real&) pagame[indice] : importo;
somma += curpag_rec.get_real(PAGSCA_IMPORTO);
if (!is_key)
pagame.add(indice, somma);
}
// scrivo i record risultanti
real* cp;
for (cp = (real*) pagame.first_item(); cp != NULL; cp = (real*) pagame.succ_item())
{
TToken_string keypart;
keypart.add(curpart_rec.get(PART_TIPOCF));
keypart.add(curpart_rec.get(PART_GRUPPO));
keypart.add(curpart_rec.get(PART_CONTO));
keypart.add(curpart_rec.get(PART_SOTTOCONTO));
keypart.add(pagame.get_hashobj()->key());
const TRectype& partita = cache().get(LF_PARTITE, keypart);
_nregpag = cur.curr().get_long(MOV_NUMREG);
_nregcosto = partita.get_long(PART_NREG);
_importo = *cp;
TRecord_text recpag;
recpag.set_type("G");
trasfilepag->autoload(recpag, curpag);
trasfilepag->write(recpag);
}
}//if curpag_items..
}//for curpart =..
}//if curpart_items..
// }//if tipomov..
}//for cur =..
}//if cur_items..
chiudi_file(trasfilepag);
return true;
}
bool TInvioP::i_proforma_clifor(char tipocf)
{
TInvioP_file* trasfile = NULL;
if (tipocf == 'C')
trasfile = apri_file("clienti");
else
trasfile = apri_file("fornit");
TString80 filtro = "";
filtro.format("TIPOCF == \"%c\"", tipocf);
TRelation rel(LF_CLIFO);
rel.add(LF_COMUNI, "STATO==STATOCF|COM==COMCF", 1);
TCursor cur(&rel, filtro);
const long cur_items = cur.items();
if (cur_items != 0)
{
cur.freeze();
TRectype& cur_rec = cur.curr();
for (cur = 0; cur.pos() < cur_items; ++(cur))
{
TRecord_text rec;
rec.set_type("C");
trasfile->autoload(rec, cur);
trasfile->write(rec);
}
}
chiudi_file(trasfile);
return true;
}
//"metodo dei metodi":in base ai parametri della maschera esegue la procedura indicata
void TInvioP::invio_proforma()
{
if (_msk->get_bool(F_MOVIMENTI))
i_proforma_movimenti();
if (_msk->get_bool(F_PAGAMENTI))
i_proforma_pagamenti();
if (_msk->get_bool(F_CLIENTI))
i_proforma_clifor();
if (_msk->get_bool(F_FORNITORI))
i_proforma_clifor('F');
if (_msk->get_bool(F_CONTI))
i_proforma_conti();
}
bool TInvioP::create()
{
_msk = new TInvioP_mask();
_configfile = new TConfig("proforma.ini");
return TSkeleton_application::create();
}
bool TInvioP::destroy()
{
if (_configfile != NULL)
delete _configfile;
delete _msk;
return TSkeleton_application::destroy();
}
void TInvioP::main_loop()
{
//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;
}
TFilename configname = "cg7200a.ini"; //file configurazione della maschera
configname.custom_path();
TConfig configfile(configname);
_msk->set(F_DATAINI, configfile.get("DATA","OPZIONI"));
_msk->set(F_DESTINAZIONE, configfile.get("PERCORSO","OPZIONI"));
while (_msk->run()!=K_QUIT)
{
configfile.set("DATA", _msk->get_date(F_DATAFIN),"OPZIONI");
configfile.set("PERCORSO", _msk->get(F_DESTINAZIONE),"OPZIONI");
_dataini = _msk->get_date(F_DATAINI);
_datafin = _msk->get_date(F_DATAFIN);
const char tipoinvio = _msk->get(F_TIPOINVIO)[0];
if (tipoinvio == 'P')
invio_proforma(); //dopo aver preso i parametri dalla maschera chiama il "metodo dei metodi"
}
}
int cg7200(int argc, char **argv)
{
TInvioP a;
a.run(argc, argv, "Invio dati contabilit<69> a Proforma");
return 0;
}