Files correlati : Ricompilazione Demo : [ ] Commento : Riportata la versione aga 1.7 patch 126 sul main trunk git-svn-id: svn://10.65.10.50/trunk@9819 c028cbd2-c16b-5b4b-a496-9718f37d4682
1415 lines
49 KiB
C++
Executable File
1415 lines
49 KiB
C++
Executable File
/*
|
|
ef0800.cpp: programma di contabilizzazione effetti
|
|
Ho visto ombre di sconforto riemergere dal passato...
|
|
al largo dei bastioni di Orione
|
|
|
|
_|_|_
|
|
^/ . ..\^
|
|
___[=========]___
|
|
___-==++""" . /. . . \ . """++==-___
|
|
__-+"" __\ .. . . | .. . | . . . /__ ""+-__
|
|
/\__+-"" `-----=====\_ <O> _/=====-----' ""-+__/\
|
|
_/_/ ""="" \_\_
|
|
|
|
_________ .-~~~-..---..-~~~-. __________
|
|
-~.--<<<<<<<`-...--'.---.`--...-'>>>>>>>--.~-
|
|
=~~.-~ ````\\_`(`._.')'_//'''' ~-.~~=
|
|
[(o)/ ``.._..'' \(o)
|
|
|
|
.___________________ _-_
|
|
.\==============_=_/ ____.---'---`---.____
|
|
. \_ \ \----._________.----/
|
|
. \ \ / / `-_-'
|
|
. __,--`.`-'..'-_
|
|
. /____ ||
|
|
. `--.____,-'
|
|
|
|
|
|
Did you see my apogee ?
|
|
*/
|
|
|
|
#include <applicat.h>
|
|
#include <mask.h>
|
|
#include <modaut.h>
|
|
#include <progind.h>
|
|
#include <relation.h>
|
|
#include <tabutil.h>
|
|
#include <sheet.h>
|
|
|
|
#include "../cg/cg2101.h"
|
|
#include "../cg/cg2103.h"
|
|
#include "../cg/cgsaldac.h"
|
|
#include "../cg/cglib02.h"
|
|
#include "../ve/velib.h"
|
|
#include "ef0301.h"
|
|
#include "ef0800a.h"
|
|
|
|
#include <mov.h>
|
|
#include <rmov.h>
|
|
#include <rmoviva.h>
|
|
#include <clifo.h>
|
|
#include <effetti.h>
|
|
#include <pagsca.h>
|
|
#include <doc.h>
|
|
|
|
#define CGROWS_LIMIT 96 // Limite imposto da invii/ricezioni
|
|
|
|
#define DIST_INCASSO 'I'
|
|
#define DIST_SBF 'B'
|
|
#define DIST_SCONTO 'S'
|
|
|
|
// TContabilizzazione_effetti_app
|
|
// Applicazione di contabilizzazione effetti
|
|
class TContabilizzazione_effetti_app : public TSkeleton_application
|
|
{
|
|
TDate _data_op; // Data operazione
|
|
TString16 _cod_caus; // Codice causale
|
|
TString16 _cod_caus_pag; // Codice causale pagamenti
|
|
int _cod_es; // Codice/anno esercizio
|
|
bool _sc_enabled; // se TRUE il saldaconto di ditta e' abilitato
|
|
bool _can_write; // se TRUE e' abilitata la scrittura. Non appena rileva un errore rimane a FALSE for this instance
|
|
real _total_mov, // Totale del movimento corrente
|
|
_total_mov_val;// Same as above but in valuta
|
|
TString _desc_inc, _desc_pag; // Descrizioni movimento generato
|
|
TMask *_msk; // maschera di selezione dati
|
|
TLocalisamfile *_attiv, // file delle attivita' (per far funzionare TRegistro)
|
|
*_fcaus, // file delle causale (per far funzionare TCausale)
|
|
*_frcaus, // file delle righe causali (per far funzionare TCausale)
|
|
*_effetti, // file degli effetti (per TDistinta)
|
|
*_reffetti, // file delle righe effetti (per TDistinta)
|
|
*_cessionari, // file dei cessionari (per TDistinta)
|
|
*_part, // file delle partite (per far funzionare TPartita)
|
|
*_scad, // file delle scadenze (per far funzionare TPartita)
|
|
*_pags, // file dei pagamenti (per far funzionare TPartita)
|
|
*_clifo, // file dei clienti
|
|
*_doc, // file dei documenti
|
|
*_pcon; // file piano dei conti
|
|
TTable *_cpg, // tabella condizioni di pagamento
|
|
*_bnp; // tabella banca presentazione effetti
|
|
TBill _banca, // conto di contropartita della banca
|
|
_cliente, // conto di contropartita del cliente
|
|
_trandiffcam; // conto di transizione per differenze cambi
|
|
TArray_sheet *_dist_sheet; // array_sheet di distinte selezionabili per la conatabilizzazione
|
|
TDistinta *_distinta; // Distinta per le elaborazioni
|
|
TPartite_array *_part_array; // Array di partite da scrivere
|
|
TMovimentoPN *_movimento; // Movimento di prima nota
|
|
TSaldo_agg _saldo; // Saldo da aggiornare
|
|
TCausale *_caus; // Causale contabile per le elaborazioni
|
|
error_type _error; // Errore rilevato durante l'elaborazione
|
|
long _total_bills; // Totale distinte contabilizzate.
|
|
int _cur_dist_row;// Numero di riga distinta corrente (per visualizzazione errore)
|
|
bool _dett_rate_att;// Dettaglia le rate su effetti attivi
|
|
bool _dett_rate_pas;// Dettaglia le rate su effetti passivi
|
|
|
|
protected: // TApplication
|
|
// Compila la testata del movimento
|
|
void compile_head_mov();
|
|
// Compila la riga di partita
|
|
void compile_riga_partita(TRiga_partite& riga, const TEffetto& effetto, const TRectype& riga_effetto, int numrig);
|
|
// Compila la riga di pagamento
|
|
void compile_riga_pagamento(TRectype& riga_pagamento, const TEffetto& effetto, const TRectype& riga_effetto, char acc_sal);
|
|
// Funzione di aggiornamento saldi una volta generato il movimento
|
|
void aggiorna_saldi();
|
|
// scrive il movimento e le scadenze
|
|
error_type write_all(bool chage_status = TRUE);
|
|
// cerca il conto di contropartita per la distinta corrente (setta _banca)
|
|
error_type search_bank_counter_bill(int tipopag=0);
|
|
// cerca il conto clienti
|
|
error_type search_clifo_bill(char tipo, const long codcf);
|
|
// ritorna la sezione corretta per la riga di partita
|
|
char sezione() const;
|
|
// Ordina le righe di un effetto
|
|
int sort_eff(TRecord_array& sorted);
|
|
// aggiunge una riga all'array dei clienti da una riga effetto
|
|
bool add_cg_row(const TEffetto& eff, const TRectype& reff, TArray& customers, TAssoc_array& banks, bool add_desc);
|
|
// somma ad una riga all'array dei clienti una riga effetto
|
|
void sum_cg_row(const TRectype& reff, TArray& customers, TAssoc_array& banks);
|
|
// aggiunge le righe spese al movimento
|
|
bool add_spese_rows(const real& spese);
|
|
// aggiunge riga pagamento da riga effetto
|
|
void compile_saldac(const TEffetto& eff, const TRectype& reff,
|
|
TImporto& abbuoni_att, TImporto& abbuoni_pas, TArray& differenze_cam,
|
|
TArray& customers);
|
|
// Controlla se il pagamento dell'effetto avra' differenze cambio
|
|
bool has_diffcam(const TEffetto& eff) const;
|
|
|
|
// Aggiunge una riga contabile al movimento
|
|
void join_row(const TRectype& row);
|
|
|
|
// unisce gli array clienti/banche nel record array delle righe contabili
|
|
void join_rows(TArray& customers, TAssoc_array& banks,
|
|
const TImporto& abbuoni_att, const TImporto& abbuoni_pas,
|
|
const TArray& differenze_cam, const real& spese);
|
|
// Visualizza l'ultimo errore rilevato
|
|
void display_error();
|
|
// Contabilizza l'effetto corrente
|
|
void contabilize_bill(const char tipo, const long numero);
|
|
// Contabilizza gli effetti
|
|
void contabilize();
|
|
// costruisce lo sheet delle distinte
|
|
void build_dist_sheet();
|
|
// Handler della selezione distinte
|
|
static bool handle_select(TMask_field& f, KEY k);
|
|
// Handler del pulsante di reset
|
|
static bool handle_reset(TMask_field& f, KEY k);
|
|
// Le 4 seguenti non hanno bisogno di commenti
|
|
virtual void main_loop();
|
|
virtual bool create();
|
|
virtual bool destroy();
|
|
virtual void on_config_change();
|
|
public:
|
|
// Verifica se non ci sono stati errori
|
|
bool good() const { return _error == no_error;}
|
|
error_type status() { return _error; }
|
|
void set_status(error_type e) { _error = e; }
|
|
TContabilizzazione_effetti_app() : _msk(NULL) {}
|
|
virtual ~TContabilizzazione_effetti_app() { }
|
|
};
|
|
|
|
inline TContabilizzazione_effetti_app& app() { return (TContabilizzazione_effetti_app&) main_app(); }
|
|
|
|
void TContabilizzazione_effetti_app::build_dist_sheet()
|
|
{
|
|
TRelation eff_rel(LF_EFFETTI);
|
|
TCursor cur_dist(&eff_rel,"TIPODIST!=\"\"",4);
|
|
TRectype& rec = cur_dist.curr();
|
|
const long items = cur_dist.items();
|
|
|
|
_dist_sheet->destroy(); // resetta lo sheet delle distinte
|
|
if (items > 0)
|
|
{
|
|
cur_dist.freeze();
|
|
|
|
cur_dist = 0;
|
|
long ndist_prec = rec.get_long(EFF_NDIST);
|
|
char tipo_prec = rec.get_char(EFF_TIPODIST);
|
|
|
|
TString16 codabi, codcab, codval;
|
|
bool enabled = TRUE;
|
|
int num_eff = 0;
|
|
|
|
for (long i = 0; i < items; i++)
|
|
{
|
|
cur_dist = i;
|
|
const long ndist = rec.get_long(EFF_NDIST);
|
|
const char tipo = rec.get_char(EFF_TIPODIST);
|
|
if (ndist != ndist_prec || tipo != tipo_prec)
|
|
{
|
|
TToken_string * t = new TToken_string;
|
|
t->add(" ");t->add(tipo_prec);
|
|
t->add(ndist_prec);
|
|
t->add(num_eff);
|
|
t->add(codabi);
|
|
t->add(codcab);
|
|
t->add(codval);
|
|
const long pos = _dist_sheet->add(t); //aggiunge una riga allo sheet delle distinte
|
|
_dist_sheet->enable_row(pos, enabled);
|
|
ndist_prec = ndist;
|
|
tipo_prec = tipo;
|
|
enabled = TRUE;
|
|
num_eff = 0;
|
|
}
|
|
if (num_eff == 0)
|
|
{
|
|
codabi = rec.get(EFF_CODABIP); // Memorizza dati della prima riga
|
|
codcab = rec.get(EFF_CODCABP);
|
|
codval = rec.get(EFF_CODVAL);
|
|
}
|
|
num_eff++; // numero di effetti che compongono la distinta
|
|
enabled &= !rec.get_bool(EFF_EFFCONT);
|
|
}
|
|
|
|
TToken_string * t = new TToken_string;
|
|
|
|
t->add(" ");t->add(tipo_prec);
|
|
t->add(ndist_prec);
|
|
t->add(num_eff);
|
|
t->add(codabi);
|
|
t->add(codcab);
|
|
t->add(rec.get(EFF_CODVAL));
|
|
|
|
const long pos = _dist_sheet->add(t); //aggiunge una riga allo sheet delle distinte
|
|
_dist_sheet->enable_row(pos, enabled);
|
|
}
|
|
}
|
|
|
|
bool TContabilizzazione_effetti_app::handle_reset(TMask_field& f, KEY k)
|
|
{
|
|
if (k == K_SPACE)
|
|
{
|
|
app()._dist_sheet->check(-1, FALSE);
|
|
f.mask().reset(F_DISTINTE);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
bool TContabilizzazione_effetti_app::handle_select(TMask_field& f, KEY k)
|
|
{
|
|
if (k==K_SPACE) // ricerca
|
|
{
|
|
TArray_sheet* sh = app()._dist_sheet;
|
|
|
|
if (sh->run() == K_ENTER)
|
|
f.mask().set(F_DISTINTE,sh->checked());
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void TContabilizzazione_effetti_app::on_config_change()
|
|
{
|
|
TPartita::carica_allineamento();
|
|
|
|
TConfig conf(CONFIG_DITTA, "ef");
|
|
_cod_caus = conf.get("CODCAUS"); // implementare programma di gestione parametri effetti
|
|
_cod_caus_pag = conf.get("CODCAUSPAG"); // implementare programma di gestione parametri effetti
|
|
_desc_inc = conf.get("DESCINC", NULL, -1, "Distinta d'incasso");
|
|
_desc_pag = conf.get("DESCPAG", NULL, -1, "Ordine di pagamento");
|
|
_dett_rate_att = conf.get_bool("DETRATATT"); // Dettaglio rate su effetti attivi
|
|
_dett_rate_pas = conf.get_bool("DETRATPAS"); // Dettaglio rate su effetti passivi
|
|
|
|
const long trans = conf.get_long("DIFFCAMS");
|
|
if (trans > 0)
|
|
_trandiffcam.set(conf.get_int("DIFFCAMG"), conf.get_int("DIFFCAMC"), trans);
|
|
|
|
_sc_enabled = conf.get_bool("GesSal","cg");
|
|
if (!has_module(CGAUT) && _sc_enabled)
|
|
{
|
|
error_box("Impossibile contabilizzare gli effetti se il modulo Contabilita' Generale non e' abilitato");
|
|
stop_run();
|
|
}
|
|
}
|
|
|
|
bool TContabilizzazione_effetti_app::create()
|
|
{
|
|
open_files(LF_TAB, LF_TABCOM, LF_CAUSALI, LF_RCAUSALI,
|
|
LF_EFFETTI, LF_REFFETTI, LF_CESS,
|
|
LF_MOV, LF_RMOV, LF_PARTITE, LF_SCADENZE, LF_PAGSCA,
|
|
LF_DOC, LF_CLIFO, LF_ATTIV, LF_PCON, LF_SALDI, 0);
|
|
|
|
_caus = NULL;
|
|
_error = no_error;
|
|
_can_write = TRUE;
|
|
_msk = new TMask("ef0800a");
|
|
_msk->set_handler(F_SELECT,handle_select);
|
|
_msk->set_handler(F_RESET,handle_reset);
|
|
_cpg = new TTable("%CPG");
|
|
_bnp = new TTable("BNP");
|
|
_clifo = new TLocalisamfile(LF_CLIFO);
|
|
_doc = new TLocalisamfile(LF_DOC);
|
|
_distinta = new TDistinta;
|
|
_movimento = new TMovimentoPN;
|
|
_dist_sheet = new TArray_sheet(-1, -1, -4, -4, "Selezione distinte",
|
|
"@1|Tipo|Numero distinta@R|Numero effetti@R|ABI@5|CAB@5|Valuta");
|
|
_part_array = new TPartite_array;
|
|
return TSkeleton_application::create();
|
|
}
|
|
|
|
bool TContabilizzazione_effetti_app::destroy()
|
|
{
|
|
if (_msk) delete _msk;
|
|
if (_cpg) delete _cpg;
|
|
if (_bnp) delete _bnp;
|
|
if (_clifo)delete _clifo;
|
|
if (_doc)delete _doc;
|
|
if (_caus) delete _caus;
|
|
if (_distinta) delete _distinta;
|
|
if (_movimento) delete _movimento;
|
|
if (_dist_sheet) delete _dist_sheet;
|
|
if (_part_array) delete _part_array;
|
|
return TApplication::destroy();
|
|
}
|
|
|
|
void TContabilizzazione_effetti_app::main_loop()
|
|
{
|
|
build_dist_sheet();
|
|
|
|
// Preselezione della distinta specificata sulla riga di comando
|
|
if (argc() >= 4)
|
|
{
|
|
const char tip = *argv(2);
|
|
const long num = atol(argv(3));
|
|
for (int r = 0; r < _dist_sheet->items(); r++)
|
|
{
|
|
TToken_string& row = _dist_sheet->row(r);
|
|
if (row.get_char(1) == tip && row.get_long(2) == num)
|
|
{
|
|
_dist_sheet->check(r);
|
|
break;
|
|
}
|
|
}
|
|
_msk->set(F_DISTINTE, _dist_sheet->checked());
|
|
}
|
|
|
|
_msk->set(F_DETT_RATE_ATT, _dett_rate_att ? "X" : "");
|
|
_msk->set(F_DETT_RATE_PAS, _dett_rate_pas ? "X" : "");
|
|
|
|
while (_msk->run() == K_ENTER)
|
|
{
|
|
if (!_dist_sheet->one_checked())
|
|
{
|
|
error_box("Nessuna distinta selezionata");
|
|
continue;
|
|
}
|
|
_data_op = _msk->get_date(F_DATA_OP);
|
|
if (!_data_op.ok()) _data_op = TODAY;
|
|
|
|
// if (_caus != NULL) delete _caus;
|
|
// _caus = new TCausale(_cod_caus,_data_op.year());
|
|
// if (!_caus->ok())
|
|
// {
|
|
// error_box("Causale contabile non valida o non presente in parametri effetti");
|
|
// continue;
|
|
// }
|
|
TEsercizi_contabili esc;
|
|
esc.update();
|
|
_cod_es = esc.date2esc(_data_op);
|
|
if (_cod_es <= 0)
|
|
{
|
|
error_box("La data operazione non appartiene a nessun esercizio");
|
|
continue;
|
|
}
|
|
|
|
_dett_rate_att = _msk->get_bool(F_DETT_RATE_ATT);
|
|
_dett_rate_pas = _msk->get_bool(F_DETT_RATE_PAS);
|
|
|
|
contabilize();
|
|
_msk->reset(F_DISTINTE);
|
|
build_dist_sheet();
|
|
}
|
|
}
|
|
|
|
void TContabilizzazione_effetti_app::display_error()
|
|
{
|
|
TString msg;
|
|
|
|
switch (_error)
|
|
{
|
|
case clifo_error:
|
|
msg.format("Non e' possibile reperire il cliente/fornitore relativamente alla distinta %c %ld. "
|
|
"Controllare la riga %d",_distinta->tipodist(), _distinta->ndist(),_cur_dist_row+1);
|
|
break;
|
|
case bank_error:
|
|
msg.format("Non e' possibile reperire i conti di contropartita per la banca di presentazione "
|
|
"relativamente alla distinta %c %ld. Controllare la tabella e la causale.",_distinta->tipodist(), _distinta->ndist());
|
|
break;
|
|
case cau_abb_error:
|
|
msg.format("Non e' possibile reperire i conti per gli abbuoni\n"
|
|
"o le differenze cambi dalla causale '%s'", _caus->codice());
|
|
break;
|
|
case cau_spe_error:
|
|
msg.format("Non e' possibile reperire il conto per le spese\n"
|
|
"dalla causale '%s'", _caus->codice());
|
|
break;
|
|
default: // Errori generici o non indicati vengono visualizzati nel punto dell'errore
|
|
break;
|
|
}
|
|
warning_box(msg);
|
|
_error = no_error; // reset error, as any other one would do, so you can show me the other ones.
|
|
_can_write = FALSE; // But from now on u cannot write anymore. U must exit this program and repair errors occurred.
|
|
}
|
|
|
|
bool TContabilizzazione_effetti_app::add_cg_row(const TEffetto& eff, const TRectype& reff, TArray& customers, TAssoc_array& banks, bool add_desc)
|
|
{
|
|
const long numreg = _movimento->curr().get_long(MOV_NUMREG);
|
|
real imp = reff.get_real(REFF_IMPORTO);
|
|
TRectype* c_rec = new TRectype(LF_RMOV);
|
|
// setta i valori per la riga cliente
|
|
c_rec->put(RMV_ANNOES,_cod_es);
|
|
c_rec->put(RMV_DATAREG,_data_op);
|
|
c_rec->put(RMV_NUMREG,numreg);
|
|
c_rec->put(RMV_SEZIONE,_caus->sezione_clifo());
|
|
_cliente.put(*c_rec);
|
|
c_rec->put(RMV_ROWTYPE,"K");
|
|
|
|
TString80 desc;
|
|
if (_cliente.tipo() == 'F')
|
|
{
|
|
if (imp >= ZERO)
|
|
desc = "Pag. ft.";
|
|
else
|
|
desc = "Nota cr.";
|
|
}
|
|
else
|
|
{
|
|
if (imp >= ZERO)
|
|
desc = "Inc. ft.";
|
|
else
|
|
desc = "Nota cr.";
|
|
}
|
|
desc << ' ' << reff.get(REFF_NFATT);
|
|
if (_cliente.tipo() == 'C')
|
|
desc << " sc. " << eff.get(EFF_DATASCAD);
|
|
c_rec->put(RMV_DESCR, desc);
|
|
if (add_desc)
|
|
{
|
|
TString80 head_desc = _movimento->curr().get(MOV_DESCR);
|
|
head_desc << ' ' << desc;
|
|
_movimento->curr().put(MOV_DESCR, head_desc);
|
|
}
|
|
|
|
// setta i valori per la riga banca
|
|
TRectype b_r(*c_rec);
|
|
TString16 key;
|
|
key.format("%3d%3d%6ld",_banca.gruppo(),_banca.conto(),_banca.sottoconto());
|
|
const bool is_present = banks.is_key(key);
|
|
TRectype& b_rec = is_present ? (TRectype&)banks.find(key) : b_r;
|
|
// setta i valori
|
|
if (!is_present) // nuova banca? allora setta la sezione ed il conto
|
|
{
|
|
const int tipopag = eff.get_int(EFF_TIPOPAG);
|
|
int nriga = 2;
|
|
if (_sc_enabled && tipopag>1 && tipopag<8)
|
|
nriga = tipopag+1;
|
|
b_rec.put(RMV_SEZIONE,_caus->sezione(nriga));
|
|
b_rec.put(RMV_TIPOC,_banca.tipo());
|
|
b_rec.put(RMV_GRUPPO,_banca.gruppo());
|
|
b_rec.put(RMV_CONTO,_banca.conto());
|
|
b_rec.put(RMV_SOTTOCONTO,_banca.sottoconto());
|
|
b_rec.put(RMV_ROWTYPE,"I");
|
|
b_rec.zero(RMV_DESCR);
|
|
}
|
|
real b_imp = b_rec.get_real(RMV_IMPORTO) + imp; // aggiorna l'importo per questa banca
|
|
b_rec.put(RMV_IMPORTO,b_imp);
|
|
banks.add(key,b_rec,is_present);
|
|
|
|
c_rec->put(RMV_IMPORTO,imp);
|
|
customers.add(c_rec);
|
|
|
|
return !is_present;
|
|
}
|
|
|
|
void TContabilizzazione_effetti_app::sum_cg_row(const TRectype& reff, TArray& customers, TAssoc_array& banks)
|
|
{
|
|
const real imp = reff.get_real(REFF_IMPORTO);
|
|
|
|
// setta i valori per la riga cliente
|
|
TRectype& c_rec = (TRectype&)customers[customers.last()];
|
|
const real c_imp = imp + c_rec.get_real(RMV_IMPORTO);
|
|
c_rec.put(RMV_IMPORTO, c_imp);
|
|
|
|
// setta i valori per la riga banca
|
|
TString16 key;
|
|
key.format("%3d%3d%6ld",_banca.gruppo(),_banca.conto(),_banca.sottoconto());
|
|
TRectype& b_rec = (TRectype&)banks.find(key);
|
|
const real b_imp = b_rec.get_real(RMV_IMPORTO) + imp; // aggiorna l'importo per questa banca
|
|
b_rec.put(RMV_IMPORTO,b_imp);
|
|
}
|
|
|
|
|
|
void TContabilizzazione_effetti_app::join_row(const TRectype& row)
|
|
{
|
|
const int n = _movimento->cg_items();
|
|
TRectype& riga = _movimento->cg(n);
|
|
riga = row;
|
|
riga.put(RMV_NUMRIG, n+1);
|
|
riga.put(RMV_ANNOES,_cod_es);
|
|
riga.put(MOV_DATAREG,_data_op);
|
|
}
|
|
|
|
bool TContabilizzazione_effetti_app::add_spese_rows(const real& spese)
|
|
{
|
|
if (spese.is_zero())
|
|
return FALSE;
|
|
|
|
TRectype& row_spese = _movimento->cg(-1);
|
|
TRectype& row_banca = _movimento->cg(-1);
|
|
|
|
TBill conto_spese; _caus->bill(11, conto_spese);
|
|
const char sez_spese = _caus->sezione(11);
|
|
const char sez_banca = sez_spese == 'D' ? 'A' : 'D';
|
|
|
|
row_spese.put(RMV_ANNOES,_cod_es);
|
|
row_spese.put(RMV_DATAREG,_data_op);
|
|
row_spese.put(RMV_SEZIONE, sez_spese);
|
|
row_spese.put(RMV_IMPORTO, spese);
|
|
conto_spese.put(row_spese);
|
|
_banca.put(row_spese, TRUE);
|
|
row_spese.put(RMV_DESCR, _caus->desc_agg(11));
|
|
if (_sc_enabled)
|
|
row_spese.put(RMV_ROWTYPE, 'G');
|
|
|
|
row_banca.put(RMV_ANNOES,_cod_es);
|
|
row_banca.put(RMV_DATAREG,_data_op);
|
|
row_banca.put(RMV_SEZIONE, sez_banca);
|
|
row_banca.put(RMV_IMPORTO, spese);
|
|
_banca.put(row_banca);
|
|
conto_spese.put(row_banca, TRUE);
|
|
if (_sc_enabled)
|
|
row_banca.put(RMV_ROWTYPE, 'L');
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void TContabilizzazione_effetti_app::join_rows(TArray& customers, TAssoc_array& banks,
|
|
const TImporto& abbuoni_att,
|
|
const TImporto& abbuoni_pas,
|
|
const TArray& differenze_cam,
|
|
const real& spese)
|
|
{
|
|
// aggiunge prima i record delle righe relative ai clienti
|
|
const int customer_items = customers.items();
|
|
for (int j=0; j<customer_items;j++)
|
|
join_row((const TRectype&) customers[j]);
|
|
|
|
// e poi i record delle righe relative alle banche
|
|
const int bank_items = banks.items();
|
|
TRectype* row;
|
|
for (j=0,row = (TRectype*)banks.first_item(); row != NULL && j<bank_items;j++,row = (TRectype *)banks.succ_item())
|
|
join_row(*row);
|
|
|
|
// infine abbuoni e differenze cambio
|
|
if (_sc_enabled)
|
|
{
|
|
TBill zio;
|
|
TRectype riga(_movimento->cg(0));
|
|
if (!abbuoni_pas.is_zero())
|
|
{
|
|
_caus->bill(9, zio); zio.put(riga);
|
|
if (!zio.ok()) _error = cau_abb_error;
|
|
riga.put(RMV_SEZIONE, abbuoni_pas.sezione());
|
|
riga.put(RMV_IMPORTO, abbuoni_pas.valore());
|
|
riga.put(RMV_ROWTYPE, "P");
|
|
join_row(riga);
|
|
}
|
|
if (!abbuoni_att.is_zero())
|
|
{
|
|
_caus->bill(10, zio); zio.put(riga);
|
|
if (!zio.ok()) _error = cau_abb_error;
|
|
riga.put(RMV_SEZIONE, abbuoni_att.sezione());
|
|
riga.put(RMV_IMPORTO, abbuoni_att.valore());
|
|
riga.put(RMV_ROWTYPE, "A");
|
|
join_row(riga);
|
|
}
|
|
if (differenze_cam.items() > 0)
|
|
{
|
|
TImporto diffcam;
|
|
for (int i = differenze_cam.items()-1; i >= 0; i--)
|
|
{
|
|
const TRectype& rec = (const TRectype&)differenze_cam[i];
|
|
TImporto dc(rec.get_char(RMV_SEZIONE), rec.get_real(RMV_IMPORTO));
|
|
diffcam += dc;
|
|
}
|
|
|
|
_caus->bill(13, zio);
|
|
if (!zio.ok())
|
|
_error = cau_abb_error;
|
|
|
|
zio.put(riga);
|
|
riga.put(RMV_SEZIONE, diffcam.sezione());
|
|
riga.put(RMV_IMPORTO, diffcam.valore());
|
|
riga.put(RMV_ROWTYPE, "C");
|
|
join_row(riga);
|
|
|
|
if (_trandiffcam.ok() && (customers.items() > 1 || differenze_cam.items() > 1))
|
|
{
|
|
TRectype& rec = _movimento->cg(_movimento->cg_items()-1);
|
|
_trandiffcam.put(rec); _trandiffcam.put(rec, TRUE);
|
|
|
|
riga.put(RMV_SEZIONE, diffcam.sezione() == 'D' ? 'A' : 'D');
|
|
_trandiffcam.put(riga); _trandiffcam.put(riga, TRUE);
|
|
riga.zero(RMV_ROWTYPE);
|
|
join_row(riga);
|
|
|
|
for (int i = 0; i < differenze_cam.items(); i++)
|
|
{
|
|
const TRectype& rec = (const TRectype&)differenze_cam[i];
|
|
join_row(rec);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (add_spese_rows(spese))
|
|
{
|
|
const char tipocf = ((const TRectype&)customers[0]).get_char(RMV_TIPOC);
|
|
if (tipocf == 'C')
|
|
_total_mov -= spese;
|
|
else
|
|
_total_mov += spese;
|
|
}
|
|
}
|
|
|
|
error_type TContabilizzazione_effetti_app::search_clifo_bill(char tipo, const long codcf)
|
|
{
|
|
_error = no_error;
|
|
_clifo->put(CLI_TIPOCF, tipo);
|
|
_clifo->put(CLI_CODCF,codcf);
|
|
_cliente.set(0,0,0);
|
|
if (_clifo->read() == NOERR)
|
|
_cliente.set(_clifo->get_int(CLI_GRUPPO),_clifo->get_int(CLI_CONTO),codcf, tipo);
|
|
if (!_cliente.ok()) // se non e' valido, reperiscilo dalla riga #1 della causale
|
|
{
|
|
_caus->bill(1,_cliente); // conto della riga 1
|
|
_cliente.codclifo() = codcf;
|
|
if (!_cliente.ok())
|
|
_error = clifo_error;
|
|
}
|
|
return _error;
|
|
}
|
|
|
|
error_type TContabilizzazione_effetti_app::search_bank_counter_bill(int tipopag)
|
|
{
|
|
// reperisce i codici ABI e CAB della banca presentazione effetti dalla
|
|
// distinta e va a cercarli sulla tabella BNP di ditta.
|
|
// La banca di presentazione effetti e' una unica per tutta la distinta
|
|
// e non puo' essere vuota
|
|
_error = no_error;
|
|
if (tipopag == 0) // cerca sulla tabella e poi sulla 2a riga di causale
|
|
{
|
|
TString16 codtab(_distinta->abip());
|
|
codtab << _distinta->cabp();
|
|
const char tipodist = _distinta->tipodist();
|
|
_banca.set(0,0,0); // resetta il conto...
|
|
_bnp->put("CODTAB",codtab);
|
|
if (_bnp->read() == NOERR)
|
|
{
|
|
TString16 fg("I0"),fc("I1"),fs("I2"); // nel caso tipodist == DIST_INCASSO
|
|
if (tipodist == DIST_SBF)
|
|
{
|
|
fg = "I3";
|
|
fc = "I4";
|
|
fs = "I5";
|
|
}
|
|
else
|
|
if (tipodist == DIST_SCONTO)
|
|
{
|
|
fg = "I6";
|
|
fc = "I7";
|
|
fs = "I8";
|
|
}
|
|
const int g = _bnp->get_int(fg);
|
|
const int c = _bnp->get_int(fc);
|
|
const long s = _bnp->get_long(fs);
|
|
_banca.set(g,c,s);
|
|
}
|
|
// se non ha trovato la banca oppure il conto, verifica che vi sia
|
|
// il conto sulla riga 2 della causale (solo se SC non abilitato)
|
|
|
|
if (!_banca.ok() && !_sc_enabled)
|
|
_caus->bill(2,_banca); // conto della riga 2
|
|
// se il saldaconto non e' abilitato, il conto di contropartita sulla causale
|
|
// va verificato per ogni riga di distinta, a seconda del tipo di pagamento.
|
|
}
|
|
else
|
|
{
|
|
// cerca il conto relativo alla riga di causale:
|
|
// 1 Rimessa diretta o contanti (banca) riga 2
|
|
// 2 Tratta riga 3
|
|
// 3 Ricevuta bancaria riga 4
|
|
// 4 Cessione riga 5
|
|
// 5 Paghero' riga 6
|
|
// 6 Lettera di credito riga 7
|
|
// 7 Tratta accettata riga 8
|
|
// 8 Rapporti interban. diretti riga 2
|
|
// 9 Bonifici riga 2
|
|
_caus->bill(tipopag>0 && tipopag<8 ? tipopag+1:2,_banca);
|
|
}
|
|
if (!_banca.ok())
|
|
_error = bank_error;
|
|
return _error;
|
|
}
|
|
|
|
char TContabilizzazione_effetti_app::sezione() const
|
|
{
|
|
char sezione = ' ';
|
|
const char tipoc = _cliente.tipo();
|
|
|
|
tipo_movimento tm = (tipo_movimento)_caus->tipomov();
|
|
sezione = _caus->sezione(1); // Usa la sezione della causale
|
|
|
|
if (sezione <= ' ') // Se non c'e' la sezione bell'e' ch'e' pronta
|
|
{
|
|
if (tm == tm_fattura || tm == tm_insoluto) // calcola in base al tipo movimento e
|
|
sezione = (tipoc == 'C') ? 'D' : 'A'; // al tipo cliente/fornitore
|
|
else
|
|
sezione = (tipoc == 'C') ? 'A' : 'D';
|
|
}
|
|
return sezione;
|
|
}
|
|
|
|
void TContabilizzazione_effetti_app::compile_head_mov()
|
|
{
|
|
CHECK(_caus,"Causale non allocata");
|
|
|
|
TLocalisamfile& mov = _movimento->lfile();
|
|
mov.last();
|
|
const long numreg = mov.get_long(MOV_NUMREG)+1; // Calcola il numero di registrazione
|
|
const TDate datadist(_distinta->data_dist());
|
|
const TDate datacam(_distinta->data_cam());
|
|
const TString80 codval(_distinta->codval());
|
|
const real cambio(_distinta->cambio());
|
|
const long ndist = _distinta->ndist();
|
|
|
|
TString des;
|
|
des = (_distinta->tipocf() == 'F') ? _desc_pag : _desc_inc;
|
|
des << ' ';
|
|
switch (_distinta->tipopag())
|
|
{
|
|
case 1: des << "rimessa diretta"; break;
|
|
case 2: des << "tratta"; break;
|
|
case 3: des << "ricevuta bancaria"; break;
|
|
case 4: des << "cessione"; break;
|
|
case 5: des << "paghero'"; break;
|
|
case 6: des << "lettera di credito"; break;
|
|
case 7: des << "tratta accettata"; break;
|
|
case 8: des << "rapp. interb. dir."; break;
|
|
case 9: des << "bonifico"; break;
|
|
default: des.rtrim(); break;
|
|
}
|
|
des << " n." << ndist;
|
|
|
|
mov.zero();
|
|
mov.put(MOV_DESCR,des);
|
|
mov.put(MOV_NUMREG,numreg);
|
|
mov.put(MOV_ANNOES,_cod_es);
|
|
mov.put(MOV_DATAREG,_data_op);
|
|
mov.put(MOV_DATACOMP,_data_op);
|
|
mov.put(MOV_DATADOC,datadist);
|
|
mov.put(MOV_NUMDOC,ndist);
|
|
mov.put(MOV_TIPODOC,_caus->tipo_doc());
|
|
mov.put(MOV_CODCAUS,_caus->codice());
|
|
mov.put(MOV_TIPOMOV,_caus->tipomov());
|
|
|
|
if (codval.not_empty())
|
|
{
|
|
mov.put(MOV_CODVAL, codval);
|
|
mov.put(MOV_DATACAM, _distinta->data_cam());
|
|
|
|
real cambio = _distinta->cambio();
|
|
const bool eurocambio = _distinta->contro_euro();
|
|
const TExchange chg(codval, cambio, eurocambio ? _exchange_contro : _exchange_base);
|
|
if (eurocambio && mov.curr().exist(MOV_CONTROEURO))
|
|
{
|
|
mov.put(MOV_CONTROEURO, eurocambio);
|
|
cambio = chg.get_contro_change();
|
|
}
|
|
else
|
|
{
|
|
cambio = chg.get_base_change();
|
|
}
|
|
mov.put(MOV_CAMBIO, cambio);
|
|
}
|
|
// MOV_TOTDOC e MOV_TOTDOCVAL vengono completati prima della scrittura del movimento
|
|
// MOV_TOTDOC e MOV_TOTDOCVAL vengono completati prima della scrittura del movimento
|
|
// e solo nel caso di saldaconto abilitato
|
|
}
|
|
|
|
void TContabilizzazione_effetti_app::compile_riga_partita(TRiga_partite& riga, const TEffetto& effetto, const TRectype& riga_effetto, int numrig)
|
|
{
|
|
TLocalisamfile& head_mov = _movimento->lfile();
|
|
riga.put(PART_TIPOMOV,_caus->tipomov());
|
|
riga.put(PART_TIPOPAG,effetto.get_int(EFF_TIPOPAG));
|
|
riga.put(PART_NREG,head_mov.get_long(MOV_NUMREG));
|
|
riga.put(PART_NUMRIG,numrig);
|
|
riga.put(PART_DATAREG,head_mov.get_date(MOV_DATAREG));
|
|
riga.put(PART_DATADOC,head_mov.get_date(MOV_DATADOC));
|
|
riga.put(PART_DATAPAG,effetto.get_date(EFF_DATASCAD));
|
|
riga.put(PART_CODCAUS,head_mov.get(MOV_CODCAUS));
|
|
riga.put(PART_NUMDOC,head_mov.get(MOV_NUMDOC)); // Sarebbe il numero della distinta...
|
|
riga.put(PART_DESCR, head_mov.get(MOV_DESCR));
|
|
riga.put(PART_SEZ,sezione());
|
|
const real imp = riga_effetto.get_real(REFF_IMPORTO);
|
|
const real imp_val = riga_effetto.get_real(REFF_IMPORTOVAL);
|
|
/* Non scrivo qui gli importi: li sommo quando faccio i pagamenti
|
|
riga.put(PART_IMPORTO,imp);
|
|
riga.put(PART_IMPORTOVAL,imp_val);
|
|
*/
|
|
riga.put(PART_CODVAL,effetto.get(EFF_CODVAL));
|
|
riga.put(PART_DATACAM,effetto.get_date(EFF_DATACAMBIO));
|
|
real cambio = effetto.get(EFF_CAMBIO);
|
|
riga.put(PART_CAMBIO, cambio);
|
|
if (effetto.get_bool(EFF_CONTROEURO))
|
|
{
|
|
if (!((TRectype&)riga).exist(PART_CONTROEURO))
|
|
{
|
|
const TExchange chg(effetto.get(EFF_CODVAL), cambio, _exchange_contro);
|
|
const real cc = chg.get_base_change();
|
|
riga.put(PART_CAMBIO, cc);
|
|
}
|
|
else
|
|
riga.put(PART_CONTROEURO, TRUE);
|
|
}
|
|
riga.put(PART_TIPOCF,_cliente.tipo());
|
|
riga.put(PART_SOTTOCONTO,_cliente.sottoconto());
|
|
riga.put(PART_IMPTOTDOC,effetto.get(EFF_IMPORTO));
|
|
riga.put(PART_IMPTOTVAL,effetto.get(EFF_IMPORTOVAL));
|
|
// PART_GRUPPOCL e PART_CONTOCL sono gia' compilati dalla TPartita::new_row()
|
|
// Aggiorna il totale movimento in lire e totale movimento in valuta (solo con saldaconto abilitato)
|
|
if (_sc_enabled)
|
|
{
|
|
_total_mov += imp;
|
|
_total_mov_val += imp_val;
|
|
}
|
|
}
|
|
|
|
void TContabilizzazione_effetti_app::compile_riga_pagamento(TRectype& riga_pagamento, const TEffetto& effetto, const TRectype& riga_effetto, char acc_sal)
|
|
{
|
|
// ANNO, NUMPART, NRIGA, NRATA, NRIGP dovrebbero essere gia' compilati
|
|
riga_pagamento.put(PAGSCA_TIPOC,_cliente.tipo());
|
|
riga_pagamento.put(PAGSCA_SOTTOCONTO,_cliente.sottoconto());
|
|
riga_pagamento.put(PAGSCA_ACCSAL,acc_sal);
|
|
riga_pagamento.put(PAGSCA_IMPORTO,riga_effetto.get_real(REFF_IMPORTO));
|
|
riga_pagamento.put(PAGSCA_IMPORTOVAL,riga_effetto.get_real(REFF_IMPORTOVAL));
|
|
riga_pagamento.put(PAGSCA_TIPOCC,_banca.tipo());
|
|
riga_pagamento.put(PAGSCA_GRUPPOC,_banca.gruppo());
|
|
riga_pagamento.put(PAGSCA_CONTOC,_banca.conto());
|
|
riga_pagamento.put(PAGSCA_SOTTOCONTC,_banca.sottoconto());
|
|
riga_pagamento.put(PAGSCA_CODABI, effetto.get(EFF_CODABI));
|
|
riga_pagamento.put(PAGSCA_CODCAB, effetto.get(EFF_CODCAB));
|
|
riga_pagamento.put(PAGSCA_CODABIPR, effetto.get(EFF_CODABIP));
|
|
riga_pagamento.put(PAGSCA_CODCABPR, effetto.get(EFF_CODCABP));
|
|
// Cerca l'eventuale codice agente sul documento
|
|
_doc->put(DOC_PROVV,riga_effetto.get(REFF_PROVV));
|
|
_doc->put(DOC_ANNO,riga_effetto.get(REFF_ANNODOC));
|
|
_doc->put(DOC_CODNUM,riga_effetto.get(REFF_CODNUM));
|
|
_doc->put(DOC_NDOC,riga_effetto.get(REFF_NFATT));
|
|
if (_doc->read() == NOERR)
|
|
riga_pagamento.put(PAGSCA_CODAG,_doc->get(DOC_CODAG));
|
|
}
|
|
|
|
void TContabilizzazione_effetti_app::compile_saldac(const TEffetto& eff,
|
|
const TRectype& reff, TImporto& abbuoni_att, TImporto& abbuoni_pas,
|
|
TArray& differenze_cam, TArray& customers)
|
|
{
|
|
int anno = reff.get_int(REFF_ANNO);
|
|
TString16 numpart = reff.get(REFF_NUMPART);
|
|
// Ricava il numero della fattura.
|
|
TString16 numdoc_to_search = reff.get(REFF_CODNUM);
|
|
TString16 nfatt = reff.get(REFF_NFATT);
|
|
TCodice_numerazione cn;
|
|
|
|
if (numdoc_to_search.not_empty() && nfatt.not_empty() && real::is_natural(nfatt))
|
|
{
|
|
cn.read(numdoc_to_search);
|
|
const long nf = atol(nfatt);
|
|
numdoc_to_search = cn.complete_num(nf);
|
|
}
|
|
else // se gli estremi della fattura non sono compilati si piglia il numero della partita
|
|
numdoc_to_search = numpart;
|
|
if (anno == 0 || numpart.empty()) // Se non sono gia' settati sulla riga effetto...
|
|
{
|
|
anno = reff.get_int(REFF_ANNODOC);// ... li va a prendere dagli estremi fattura...
|
|
if (numdoc_to_search.not_empty())
|
|
{
|
|
numpart = numdoc_to_search;
|
|
}
|
|
else // ...oppure dalla testata movimento.
|
|
{ // Appunto: da verificare se facciamo cosi' o generiamo un errore...
|
|
anno = eff.get_date(EFF_DATADIST).year();
|
|
const char all = TPartita::allineamento_richiesto(eff.get_char(EFF_TIPOCF));
|
|
if (all == 'R')
|
|
numpart.format("%7ld", eff.get_long(EFF_NDIST));
|
|
else
|
|
numpart.format("%ld", eff.get_long(EFF_NDIST));
|
|
numdoc_to_search = numpart; // A mali estremi... estremi rimedi
|
|
}
|
|
}
|
|
TPartita * partita = _part_array->exist(_cliente,anno,numpart);
|
|
if (partita == NULL) // Se la partita non esiste nell'array la aggiunge
|
|
{
|
|
partita = new TPartita(_cliente,anno,numpart);
|
|
_part_array->insert(partita);
|
|
}
|
|
TRiga_partite& riga_part = partita->new_row();
|
|
// Compila la riga di partita
|
|
const int numrig = customers.items();
|
|
compile_riga_partita(riga_part,eff,reff, numrig);
|
|
// Compila la riga di pagamento:
|
|
// reperire il numero della riga partita (nrigp) appena aggiunta
|
|
const int nrigp = riga_part.get_int(PART_NRIGA);
|
|
((TRectype&)reff).put(REFF_NRIGP, nrigp);
|
|
|
|
// scorrere le righe della partita (nriga) per trovare il riferimento alla fattura di cui si sta effettuando il pagamento
|
|
// se non la si trova allora... nriga = UNASSIGNED
|
|
const int uns = (int)TPartita::UNASSIGNED;
|
|
int nriga = reff.get_int(REFF_NRIGA);
|
|
if (nriga == 0 || nriga == uns)
|
|
{
|
|
nriga = uns;
|
|
for (int r = partita->last(); r > 0; r = partita->pred(r))
|
|
{
|
|
const TRiga_partite& rpart = partita->riga(r);
|
|
const TString16 numdoc = rpart.get(PART_NUMDOC);
|
|
if (numdoc == numdoc_to_search && rpart.is_fattura())
|
|
{
|
|
nriga = r;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
// reperire il numero di rata (nrata) dalla riga effetto
|
|
const int nrata = reff.get_int(REFF_NRATA);
|
|
char acc_sal = 'A';
|
|
if (partita->esiste(nriga,nrata)) // calcola se e' a saldo o in acconto della rata
|
|
{
|
|
acc_sal = reff.get_char(REFF_ACCSAL);
|
|
if (acc_sal != 'S' && acc_sal != 'A')
|
|
{
|
|
/*
|
|
TRiga_scadenze& riga_scadenza = partita->rata(nriga,nrata);
|
|
TImporto residuo_scadenza(riga_scadenza.residuo(FALSE));
|
|
if (residuo_scadenza.valore() <= reff.get_real(REFF_IMPORTO))
|
|
acc_sal = 'S';
|
|
else
|
|
*/
|
|
acc_sal = 'A'; // Potrebbe succedere che il ACCSAL sia vuoto
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (nriga != uns)
|
|
nriga = uns; // E' praticamente impossibile che si trovi la fattura
|
|
// senza le proprie scadenze. Al limite settiamo il numero di riga per non assegnati.
|
|
}
|
|
// Creo una nuova riga di pagamento
|
|
TRectype& old_riga_pagamento = partita->pagamento(nriga,nrata,nrigp);
|
|
// compilo i campi di riga_pagamento
|
|
TRectype riga_pagamento(old_riga_pagamento);
|
|
compile_riga_pagamento(riga_pagamento,eff,reff, acc_sal);
|
|
// Aggiorno il pagamento generando eventuali abbuoni
|
|
char old_ap, new_ap;
|
|
TImporto old_abb, new_abb, old_diffcam, new_diffcam;
|
|
|
|
const TString16 codval = eff.get(EFF_CODVAL);
|
|
const TDate datacam = eff.get(EFF_DATACAMBIO);
|
|
real cambio = eff.get(EFF_CAMBIO);
|
|
exchange_type et = eff.get_bool(EFF_CONTROEURO) ? _exchange_contro : _exchange_base;
|
|
if (et == _exchange_contro)
|
|
{
|
|
if (!((TRectype&)riga_part).exist(PART_CONTROEURO))
|
|
{
|
|
const TExchange chg(codval, cambio, et);
|
|
cambio = chg.get_base_change();
|
|
et = _exchange_base;
|
|
riga_part.put(PART_CAMBIO, cambio);
|
|
}
|
|
}
|
|
const TValuta valuta_eff(codval, datacam, cambio, et);
|
|
|
|
partita->modifica_pagamento(riga_pagamento, valuta_eff,
|
|
old_ap, old_abb, old_diffcam,
|
|
new_ap, new_abb, new_diffcam, TRUE);
|
|
|
|
// Se ci sono abbuoni o differenze cambio...
|
|
if (!new_abb.is_zero() || !new_diffcam.is_zero())
|
|
{
|
|
if (new_ap == 'A')
|
|
{
|
|
abbuoni_att -= new_abb; // Sottraggo perche' va in sezione opposta
|
|
abbuoni_att.normalize();
|
|
}
|
|
if (new_ap == 'P')
|
|
{
|
|
abbuoni_pas -= new_abb; // Sottraggo perche' va in sezione opposta
|
|
abbuoni_pas.normalize();
|
|
}
|
|
if (!new_diffcam.is_zero())
|
|
{
|
|
// Sottraggo perche' va in sezione opposta
|
|
TImporto dc = new_diffcam;
|
|
dc.normalize(); dc.swap_section();
|
|
|
|
TRectype* row = new TRectype(LF_RMOV);
|
|
differenze_cam.add(row);
|
|
row->put(RMV_SEZIONE, dc.sezione());
|
|
row->put(RMV_IMPORTO, dc.valore());
|
|
TBill zio; _caus->bill(13, zio);
|
|
zio.put(*row);
|
|
|
|
TString80 str; str << "ft. " << nfatt;
|
|
row->put(RMV_DESCR, str);
|
|
}
|
|
|
|
TRectype& last = (TRectype&)customers[customers.last()];
|
|
TImporto imp(last.get_char(RMV_SEZIONE), last.get_real(RMV_IMPORTO));
|
|
imp += new_abb; // Incremento con abbuoni
|
|
imp += new_diffcam; // Incremento con differenze cambi
|
|
last.put(RMV_SEZIONE, imp.sezione());
|
|
last.put(RMV_IMPORTO, imp.valore());
|
|
}
|
|
}
|
|
|
|
void TContabilizzazione_effetti_app::aggiorna_saldi()
|
|
{
|
|
CHECK(_movimento, "Movimento non valido passato ad aggiorna_saldi()");
|
|
|
|
TLocalisamfile& mov = _movimento->lfile();
|
|
|
|
const TDate datareg(mov.get_date(MOV_DATAREG));
|
|
|
|
tiposal tsal = _caus->apertura() ? apertura :
|
|
(_caus->chiusura() ? chiusura : normale);
|
|
|
|
|
|
_saldo.reset(); // Inizializza saldi
|
|
_saldo.set_movprovv(FALSE);
|
|
_saldo.set_tipo_saldo(tsal);
|
|
_saldo.set_anno_es(mov.get_int(MOV_ANNOES));
|
|
_saldo.set_num_ulmov(mov.get_long(MOV_NUMREG));
|
|
_saldo.set_data_ulmov(datareg);
|
|
_saldo.set_movimentato(TRUE);
|
|
|
|
const int cgitems = _movimento->cg_items();
|
|
for (int i = 0; i < cgitems; i++)
|
|
{
|
|
const TRectype& r = _movimento->cg(i);
|
|
TImporto import(r.get_char("SEZIONE"), r.get_real("IMPORTO"));
|
|
|
|
TBill conto; conto.get(r);
|
|
_saldo.aggiorna(conto, import, TRUE);
|
|
}
|
|
|
|
_saldo.registra();
|
|
}
|
|
|
|
error_type TContabilizzazione_effetti_app::write_all(bool change_status)
|
|
{
|
|
TRectype& head = _movimento->lfile().curr();
|
|
head.put(MOV_TOTDOC,_total_mov);
|
|
head.put(MOV_TOTDOCVAL,_total_mov_val);
|
|
|
|
long orig_numreg, numreg = head.get_long(MOV_NUMREG);
|
|
orig_numreg = numreg;
|
|
while (_movimento->write() == _isreinsert)
|
|
head.put(MOV_NUMREG,++numreg);
|
|
if (_movimento->status() != NOERR)
|
|
{
|
|
error_box("E' stato rilevato l'errore %d scrivendo il movimento %ld.",_movimento->status(),numreg);
|
|
_error = generic_error;
|
|
}
|
|
|
|
if (good()) // nessun errore ?
|
|
{
|
|
aggiorna_saldi();
|
|
|
|
if (_sc_enabled) // Debbo scrivere anche le partite ?
|
|
{
|
|
if (numreg > orig_numreg) // Ha effettuato una rinumerazione ?
|
|
{
|
|
// Allora scorre le partite in _part_array e aggiorna il campo NREG delle righe di ognuna
|
|
for (TPartita * p = _part_array->first(); p != NULL; p = _part_array->next())
|
|
// Scorre le righe della partita corrente
|
|
for (int n = p->last(); n > 0; n = p->pred(n))
|
|
{
|
|
TRiga_partite& riga = p->riga(n);
|
|
if (riga.get_long(PART_NREG) == orig_numreg) // sostituisce il numero registrazione con quello nuovo
|
|
riga.put(PART_NREG, numreg);
|
|
}
|
|
}
|
|
if (!_part_array->write()) // L'errore viene gia' segnalato dalla partita
|
|
_error = generic_error;
|
|
}
|
|
if (good() && change_status) // deve anche cambiare lo stato alla distinta ?
|
|
{
|
|
TDistinta& distinta = *_distinta;
|
|
const int items = distinta.items();
|
|
for (int n = 0; n < items; n++)
|
|
{
|
|
TRectype& eff = distinta[n];
|
|
eff.put(EFF_EFFCONT, TRUE);
|
|
eff.put(EFF_NUMREG, numreg);
|
|
}
|
|
int err = distinta.rewrite();
|
|
if (err != NOERR)
|
|
{
|
|
error_box("E' stato rilevato l'errore %d aggiornando lo stato della distinta %c %ld.",err,distinta.tipodist(),distinta.ndist());
|
|
_error = generic_error;
|
|
}
|
|
}
|
|
}
|
|
|
|
return _error;
|
|
}
|
|
|
|
bool TContabilizzazione_effetti_app::has_diffcam(const TEffetto& eff) const
|
|
{
|
|
bool yes = FALSE;
|
|
if (eff.in_valuta()) // Considera solo effetti in valuta
|
|
{
|
|
const TExchange cambio(eff);
|
|
|
|
TLocalisamfile partite(LF_PARTITE);
|
|
for (int n = 1; yes == FALSE && n <= eff.rows_r(); n++)
|
|
{
|
|
const TRectype& riga = eff.row_r(n);
|
|
if (riga.get_char(REFF_ACCSAL) != 'S') // Ignora righe non saldanti
|
|
continue;
|
|
|
|
partite.put(PART_TIPOCF, eff.get(EFF_TIPOCF));
|
|
partite.put(PART_GRUPPO, 0);
|
|
partite.put(PART_CONTO, 0);
|
|
partite.put(PART_SOTTOCONTO, eff.get(EFF_CODCF));
|
|
partite.put(PART_ANNO, riga.get(REFF_ANNO));
|
|
partite.put(PART_NUMPART, riga.get(REFF_NUMPART));
|
|
partite.put(PART_NRIGA, riga.get(REFF_NRIGA));
|
|
int err = partite.read();
|
|
if (err == NOERR)
|
|
{
|
|
const TExchange cambiofatt(partite.curr());
|
|
yes = cambiofatt != cambio;
|
|
}
|
|
else
|
|
NFCHECK("Effetto pagante fattura fantasma");
|
|
}
|
|
}
|
|
return yes;
|
|
}
|
|
|
|
static void build_eff_key(const TRectype& row, TString& str, bool full = TRUE)
|
|
{
|
|
int anno = row.get_int(REFF_ANNO);
|
|
if (anno <= 0)
|
|
anno = row.get_int(REFF_ANNODOC);
|
|
|
|
TString16 part = row.get(REFF_NUMPART);
|
|
if (part.blank() || part == "0")
|
|
part = row.get(REFF_NFATT);
|
|
|
|
int riga = row.get_int(REFF_NRIGA);
|
|
if (riga <= 0)
|
|
riga = 1;
|
|
|
|
if (full)
|
|
{
|
|
const int rata = row.get_int(REFF_NRATA);
|
|
str.format("%04d|%s|%04d|%04d", anno, (const char*)part, riga, rata);
|
|
}
|
|
else
|
|
str.format("%04d|%s|%04d", anno, (const char*)part, riga);
|
|
}
|
|
|
|
static int sort_eff_func(const TObject** o1, const TObject** o2)
|
|
{
|
|
const TRectype& r1 = *((TRectype*)*o1);
|
|
const TRectype& r2 = *((TRectype*)*o2);
|
|
TString80 s1, s2;
|
|
build_eff_key(r1, s1);
|
|
build_eff_key(r2, s2);
|
|
return s2.compare(s1);
|
|
}
|
|
|
|
int TContabilizzazione_effetti_app::sort_eff(TRecord_array& rows)
|
|
{
|
|
rows.sort(sort_eff_func); // Ordina per anno/partita/fattura/rata
|
|
|
|
// Raggruppa le righe riferite alla stessa rata
|
|
TString last_key, curr_key;
|
|
for (int i = rows.last_row(); i > 0; i--)
|
|
{
|
|
TRectype& row = rows[i];
|
|
build_eff_key(row, curr_key);
|
|
if (curr_key == last_key) // Hanno la stessa rata per cui sommo e cancello l'ultima riga
|
|
{
|
|
real importo = rows[i+1].get(REFF_IMPORTO);
|
|
importo += row.get_real(REFF_IMPORTO);
|
|
row.put(REFF_IMPORTO, importo);
|
|
rows.destroy_row(i+1, TRUE);
|
|
}
|
|
else
|
|
last_key = curr_key;
|
|
}
|
|
|
|
return rows.rows();
|
|
}
|
|
|
|
void TContabilizzazione_effetti_app::contabilize_bill(const char tipo, const long numero)
|
|
{
|
|
TDistinta& distinta = *_distinta;
|
|
TLocalisamfile& mov = _movimento->lfile();
|
|
// tiene 2 array di record separati: uno per i clienti ed uno per le banche,
|
|
// alla fine, prima di scrivere il movimento, li riunisce nel record array di
|
|
// _movimento, per metterli in ordine, prima le righe clienti e poi le righe delle banche
|
|
// L'array delle banche e' un assoc_array, con indice sul gruppo/conto/sottoconto
|
|
// per effettuare il raggruppamento
|
|
TArray customers;
|
|
TAssoc_array banks;
|
|
TArray differenze_cam;
|
|
TImporto abbuoni_att, abbuoni_pas;
|
|
|
|
bool reset_bank = FALSE;
|
|
_total_mov = 0.0;
|
|
_total_mov_val = 0.0;
|
|
distinta.read(tipo,numero,_lock); // Sblocca da solo quella precedente
|
|
if (_caus != NULL)
|
|
delete _caus;
|
|
|
|
const char* cc = distinta.tipocf() == 'F' ? _cod_caus_pag : _cod_caus;
|
|
_caus = new TCausale(cc, _data_op.year());
|
|
if (!_caus->ok())
|
|
{
|
|
_error = generic_error;
|
|
error_box("Causale '%s' non valida o non presente in parametri effetti", cc);
|
|
return;
|
|
}
|
|
|
|
//Cerca il conto della contropartita della banca di presentazione.
|
|
//Nel caso in cui sia presente sulla tabella BNP (selezione anche per
|
|
//tipo distinta) il conto sara' unico per tutti; se invece non e' presente sul file oppure il conto
|
|
//di contropartita e' vuoto, andra' reperito per ogni effetto, a seconda della causale
|
|
//impostata e del tipo di pagamento (quest'ultimo solo nel caso di saldaconto abilitato); altrimenti si
|
|
//terra' per buono sempre quello della seconda riga della casuale .
|
|
//E' chiaro che nella maggioranza dei casi si avra' sempre un unico conto di contropartita, definito
|
|
//nella tabella BNP.
|
|
//Non meno importante: nel caso avessimo piu' conti di contropartita per le banche
|
|
//si dovra' procedere ad un raggruppamento, sommando gli importi (mentre invece le righe
|
|
//clienti non dovranno subire tale procedimento.
|
|
//Infine: a causa del cazzutissimo limite di 99 righe contabili settato in invii/ricezioni
|
|
//si dovranno generare piu' movimenti per un stessa distinta se le righe eccedono tale
|
|
//valore (come avere le palle sopra un'incudine ed una mazza ferrata che sta per piombare a tutta forza...)
|
|
search_bank_counter_bill();
|
|
if (!good())
|
|
return; // _error's already set
|
|
|
|
real spese = distinta[0].get(EFF_SPESE);
|
|
TBill conto_cassa, conto_spese;
|
|
if (!spese.is_zero())
|
|
{
|
|
_caus->bill(11, conto_spese);
|
|
if (!conto_spese.ok())
|
|
{
|
|
_error = cau_spe_error;
|
|
return;
|
|
}
|
|
}
|
|
|
|
bool dettaglio_rate = FALSE;
|
|
if (distinta.tipocf() == 'F')
|
|
dettaglio_rate = _dett_rate_pas;
|
|
else
|
|
dettaglio_rate = _dett_rate_att;
|
|
|
|
const int items = distinta.items(); // Perche' sul file effetti il numero riga distinta e' un long ??
|
|
|
|
// compila la testata
|
|
compile_head_mov();
|
|
|
|
// _cur_dist_row e' un int sebbene su file sia un long: TArray::items() ritorna un int!!
|
|
for (_cur_dist_row = 0; _cur_dist_row<items; _cur_dist_row++) // scorre le righe della distinta (effetti)
|
|
{
|
|
const TEffetto& eff = distinta[_cur_dist_row];
|
|
const long codcf = eff.get_long(EFF_CODCF);
|
|
const char tipo = eff.get_tipo();
|
|
search_clifo_bill(tipo, codcf);
|
|
|
|
if (!good()) break;
|
|
|
|
// se la banca non e' stata settata cerca il conto sulla causale a seconda del tipo di pagamento di questo effetto
|
|
if (!_banca.ok() || reset_bank)
|
|
{
|
|
search_bank_counter_bill(eff.get_int(EFF_TIPOPAG));
|
|
if (!good()) break;
|
|
reset_bank = TRUE; // forza la ricerca del conto della banca ad ogni riga distinta
|
|
}
|
|
const bool force_break = !_trandiffcam.ok() && has_diffcam(eff);
|
|
|
|
TRecord_array sorted = ((TEffetto&)eff).righe();
|
|
sort_eff(sorted);
|
|
|
|
TString last_key, curr_key;
|
|
|
|
for (int n = 1; n <= sorted.rows(); n++)
|
|
{
|
|
const TRectype& riga = sorted[n];
|
|
build_eff_key(riga, curr_key, FALSE);
|
|
|
|
if (n == 1 || (dettaglio_rate && curr_key != last_key))
|
|
{
|
|
add_cg_row(eff, riga, customers, banks, FALSE);
|
|
last_key = curr_key;
|
|
}
|
|
else
|
|
sum_cg_row(riga, customers, banks);
|
|
|
|
if (_sc_enabled)
|
|
compile_saldac(eff, riga, abbuoni_att, abbuoni_pas, differenze_cam, customers);
|
|
|
|
// Calcola il numero di righe contabili generate fino ad ora.
|
|
// per i clienti e' sempre vero, mentre per le banche dipende
|
|
// se e' stato fatto un raggruppamento
|
|
int nrows = customers.items() + banks.items();
|
|
if (_sc_enabled)
|
|
{
|
|
if (!abbuoni_att.is_zero()) nrows++;
|
|
if (!abbuoni_pas.is_zero()) nrows++;
|
|
nrows+=differenze_cam.items();
|
|
}
|
|
if (!spese.is_zero())
|
|
nrows += 2;
|
|
|
|
if (nrows > 0 && force_break) // Se ci sono differenze cambio ...
|
|
nrows = CGROWS_LIMIT; // ... allora forza cambio movimento
|
|
|
|
if (nrows >= CGROWS_LIMIT) // se sono arrivato al limite massimo, scrivo questo movimento
|
|
{
|
|
// Unisce le righe banche e clienti nel record_array delle righe contabili
|
|
if (good() && _can_write)
|
|
{
|
|
join_rows(customers, banks, abbuoni_att, abbuoni_pas, differenze_cam, spese);
|
|
if (good())
|
|
write_all(FALSE); // non cambiare lo stato della distinta, cambialo solo alla fine
|
|
}
|
|
if (good())
|
|
{
|
|
_movimento->destroy_rows(mov.get_long(MOV_NUMREG)); // azzera le righe..
|
|
_part_array->destroy(); // e l'array delle partite
|
|
customers.destroy();
|
|
banks.destroy();
|
|
differenze_cam.destroy();
|
|
abbuoni_att = abbuoni_pas = TImporto('A', ZERO);
|
|
_total_mov = ZERO;
|
|
_total_mov_val = ZERO;
|
|
spese = ZERO;
|
|
// compila la testata del nuovo movimento
|
|
compile_head_mov();
|
|
}
|
|
}
|
|
if (!good()) break;
|
|
}
|
|
} // Ciclo su effetti
|
|
|
|
if (good() && _can_write && customers.items()) // scrive il movimento residuo ...
|
|
{
|
|
join_rows(customers, banks, abbuoni_att, abbuoni_pas, differenze_cam, spese);
|
|
if (good() && write_all() == no_error) // Se la scrittura e' andata ok...
|
|
_total_bills++; // incrementa il numero di distinte contabilizzate
|
|
}
|
|
_movimento->destroy_rows(mov.get_long(MOV_NUMREG)); // azzera le righe..
|
|
_part_array->destroy(); // e l'array delle partite
|
|
}
|
|
|
|
void TContabilizzazione_effetti_app::contabilize()
|
|
{
|
|
_total_bills = 0;
|
|
|
|
const long cur_items = _dist_sheet->items(); // Quante distinte in totale ?
|
|
TProgind p(cur_items, "Contabilizzazione effetti", FALSE, TRUE);
|
|
for (long j = 0; j < cur_items; j++)
|
|
{
|
|
p.setstatus(j+1);
|
|
if (_dist_sheet->checked(j))
|
|
{
|
|
TToken_string& t = _dist_sheet->row(j);
|
|
const char tipo = t.get_char(1);
|
|
const long numero = t.get_long(2);
|
|
contabilize_bill(tipo,numero);
|
|
if (!good())
|
|
display_error();
|
|
}
|
|
}
|
|
if (_total_bills > 0)
|
|
{
|
|
TConfig conf(CONFIG_DITTA, "ef");
|
|
conf.set("DETRATATT", _dett_rate_att ? "X" : "");
|
|
conf.set("DETRATPAS", _dett_rate_pas ? "X" : "");
|
|
|
|
message_box("Totale effetti contabilizzati: %ld",_total_bills);
|
|
}
|
|
}
|
|
|
|
int ef0800 (int argc, char* argv[])
|
|
{
|
|
TContabilizzazione_effetti_app a;
|
|
a.run(argc,argv,"Contabilizzazione effetti");
|
|
return TRUE;
|
|
}
|