Files correlati : ef0.exe ef0100a.msk ef0300a.msk ef0800a.msk Ricompilazione Demo : [ ] Commento : GF20044 Pur avendo inserito, nella relativa tabella, le banche di presentazione quando cerco di inserire una distinta sulla bamca xy appare il seguente messaggio d'errore:"VALORE NON VALIDO PER BANCA DI PRESENTAZIONE XY" GF20045 Nella pagina parametri banche di presentazione se vado in ricerca non mi appare la denominazione della Banca. GF20046 Ho generato degli effetti raggruppati creando tre ricevute bancarie dell'importo della fattura al netto dell'importo della nota di credito, nell'operazione contabile di contabilizzazione della relativa distinta di presentazione non riesce a chiudere correttamente le partite o meglio crea in fondo alla partita delle righe 9999 rata 9999 invece di chiudere la rata corrispondente. git-svn-id: svn://10.65.10.50/trunk@11283 c028cbd2-c16b-5b4b-a496-9718f37d4682
1493 lines
50 KiB
C++
Executable File
1493 lines
50 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 <automask.h>
|
|
#include <modaut.h>
|
|
#include <progind.h>
|
|
#include <relation.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_mask
|
|
|
|
class TContabilizzazione_mask : public TAutomask
|
|
{
|
|
protected:
|
|
virtual bool on_field_event(TOperable_field& f, TField_event e, long jolly);
|
|
|
|
public:
|
|
TContabilizzazione_mask();
|
|
};
|
|
|
|
// 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
|
|
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; }
|
|
|
|
TArray_sheet& dist_sheet() { return *_dist_sheet; }
|
|
|
|
TContabilizzazione_effetti_app() : _msk(NULL) {}
|
|
virtual ~TContabilizzazione_effetti_app() { }
|
|
};
|
|
|
|
inline TContabilizzazione_effetti_app& app() { return (TContabilizzazione_effetti_app&) main_app(); }
|
|
|
|
// TContabilizzazione_mask
|
|
|
|
bool TContabilizzazione_mask::on_field_event(TOperable_field& f, TField_event e, long jolly)
|
|
{
|
|
switch (f.dlg())
|
|
{
|
|
case F_DATA_OP:
|
|
if (e == fe_modify || e == fe_close)
|
|
{
|
|
const TDate data = f.get();
|
|
TEsercizi_contabili esc;
|
|
if (esc.date2esc(data) <= 0)
|
|
return error_box(TR("La data deve appartenere ad un esercizio valido"));
|
|
}
|
|
break;
|
|
case F_RESET:
|
|
if (e == fe_button)
|
|
{
|
|
app().dist_sheet().check(-1, FALSE);
|
|
reset(F_DISTINTE);
|
|
}
|
|
break;
|
|
case F_SELECT:
|
|
if (e == fe_button)
|
|
{
|
|
TArray_sheet& sh = app().dist_sheet();
|
|
if (sh.run() == K_ENTER)
|
|
set(F_DISTINTE,sh.checked());
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
TContabilizzazione_mask::TContabilizzazione_mask()
|
|
: TAutomask("ef0800a")
|
|
{
|
|
}
|
|
|
|
// TContabilizzazione_effetti_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;
|
|
char tipocf;
|
|
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);
|
|
t->add(tipocf);
|
|
t->add(rec.get(EFF_DATADIST));
|
|
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);
|
|
tipocf = rec.get_char(EFF_TIPOCF);
|
|
}
|
|
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));
|
|
t->add(rec.get(EFF_TIPOCF));
|
|
t->add(rec.get(EFF_DATADIST));
|
|
|
|
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(TR("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 TContabilizzazione_mask();
|
|
_distinta = new TDistinta;
|
|
_movimento = new TMovimentoPN;
|
|
_dist_sheet = new TArray_sheet(-1, -1, -4, -4, TR("Selezione distinte"),
|
|
HR("@1|Tipo|Numero distinta@R|Numero effetti@R|ABI@5|CAB@5|Valuta|C/F|Data Dist."));
|
|
_part_array = new TPartite_array;
|
|
return TSkeleton_application::create();
|
|
}
|
|
|
|
bool TContabilizzazione_effetti_app::destroy()
|
|
{
|
|
if (_msk) delete _msk;
|
|
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(TR("Nessuna distinta selezionata"));
|
|
continue;
|
|
}
|
|
_data_op = _msk->get_date(F_DATA_OP);
|
|
|
|
TEsercizi_contabili esc;
|
|
_cod_es = esc.date2esc(_data_op);
|
|
_dett_rate_att = _msk->get_bool(F_DETT_RATE_ATT);
|
|
_dett_rate_pas = _msk->get_bool(F_DETT_RATE_PAS);
|
|
|
|
// Salva parametri per la prossima volta
|
|
{
|
|
TConfig conf(CONFIG_DITTA, "ef");
|
|
conf.set("DETRATATT", _dett_rate_att ? "X" : "");
|
|
conf.set("DETRATPAS", _dett_rate_pas ? "X" : "");
|
|
}
|
|
|
|
contabilize();
|
|
_msk->reset(F_DISTINTE);
|
|
build_dist_sheet();
|
|
}
|
|
}
|
|
|
|
void TContabilizzazione_effetti_app::display_error()
|
|
{
|
|
TString msg;
|
|
|
|
switch (_error)
|
|
{
|
|
case clifo_error:
|
|
msg.format(FR("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(FR("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(FR("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(FR("Non e' possibile reperire il conto per le spese\n"
|
|
"dalla causale '%s'"), _caus->codice());
|
|
break;
|
|
case datadoc_error:
|
|
msg.format(FR("La data distinta %s non appartiene ad un esercizio valido"),
|
|
(const char*)_distinta->data_dist().string());
|
|
|
|
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);
|
|
|
|
if (_sc_enabled)
|
|
c_rec->put(RMV_ROWTYPE,"K");
|
|
|
|
TString80 desc;
|
|
if (_cliente.tipo() == 'F')
|
|
{
|
|
if (imp >= ZERO)
|
|
desc = TR("Pag. ft.");
|
|
else
|
|
desc = TR("Nota cr.");
|
|
}
|
|
else
|
|
{
|
|
if (imp >= ZERO)
|
|
desc = TR("Inc. ft.");
|
|
else
|
|
desc = TR("Nota cr.");
|
|
}
|
|
desc << ' ' << reff.get(REFF_NFATT);
|
|
if (_cliente.tipo() == 'C')
|
|
desc << TR(" 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());
|
|
if (_sc_enabled)
|
|
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;
|
|
TString16 key;
|
|
|
|
key.format("%c|%ld", tipo, codcf);
|
|
|
|
const TRectype & clifo = cache().get(LF_CLIFO, key);
|
|
|
|
if (clifo.empty())
|
|
_cliente.set(0,0,0);
|
|
else
|
|
_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
|
|
{
|
|
_banca.set(0,0,0); // resetta il conto...
|
|
|
|
TString16 codtab(_distinta->abip());
|
|
codtab << _distinta->cabp();
|
|
const TRectype& bnp = cache().get("BNP", codtab);
|
|
if (!bnp.empty())
|
|
{
|
|
const char* fg;
|
|
const char* fc;
|
|
const char* fs;
|
|
const char tipodist = _distinta->tipodist();
|
|
switch (tipodist)
|
|
{
|
|
case DIST_SBF:
|
|
fg = "I3"; fc = "I4"; fs = "I5";
|
|
break;
|
|
case DIST_SCONTO:
|
|
fg = "I6"; fc = "I7"; fs = "I8";
|
|
break;
|
|
case DIST_INCASSO: // Default
|
|
default:
|
|
if (_distinta->tipocf() == 'F')
|
|
{
|
|
fg = "I9"; fc = "I10"; fs = "I11";
|
|
}
|
|
else
|
|
{
|
|
fg = "I0"; fc = "I1"; fs = "I2";
|
|
}
|
|
break;
|
|
}
|
|
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();
|
|
|
|
TEsercizi_contabili esc;
|
|
if (esc.date2esc(datadist) <= 0)
|
|
{
|
|
if (!yesno_box(FR("Attenzione: la data distinta %s non appartiene ad un esercizio valido:\n"
|
|
"Si desidera proseguire ugualmente?"), (const char*)datadist.string()))
|
|
{
|
|
_can_write = FALSE;
|
|
return;
|
|
}
|
|
}
|
|
|
|
TString des;
|
|
des = (_distinta->tipocf() == 'F') ? _desc_pag : _desc_inc;
|
|
des << ' ';
|
|
switch (_distinta->tipopag())
|
|
{
|
|
case 1: des << TR("rimessa diretta"); break;
|
|
case 2: des << TR("tratta"); break;
|
|
case 3: des << TR("ricevuta bancaria"); break;
|
|
case 4: des << TR("cessione"); break;
|
|
case 5: des << TR("paghero'"); break;
|
|
case 6: des << TR("lettera di credito"); break;
|
|
case 7: des << TR("tratta accettata"); break;
|
|
case 8: des << TR("rapp. interb. dir."); break;
|
|
case 9: des << TR("bonifico"); break;
|
|
default: des.rtrim(); break;
|
|
}
|
|
des << TR(" 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
|
|
// 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)
|
|
{
|
|
const TRectype& head_mov = _movimento->curr();
|
|
riga.put(PART_TIPOMOV,_caus->tipomov());
|
|
riga.put(PART_TIPOPAG,effetto.get(EFF_TIPOPAG));
|
|
riga.put(PART_NREG,head_mov.get(MOV_NUMREG));
|
|
riga.put(PART_NUMRIG,numrig);
|
|
riga.put(PART_DATAREG,head_mov.get(MOV_DATAREG));
|
|
riga.put(PART_DATADOC,head_mov.get(MOV_DATADOC));
|
|
riga.put(PART_DATAPAG,effetto.get(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(REFF_IMPORTO);
|
|
const real imp_val = riga_effetto.get(REFF_IMPORTOVAL);
|
|
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
|
|
|
|
TString key(30);
|
|
|
|
key << riga_effetto.get(REFF_PROVV) << "|";
|
|
key << riga_effetto.get(REFF_ANNODOC) << "|";
|
|
key << riga_effetto.get(REFF_CODNUM) << "|";
|
|
key << riga_effetto.get(REFF_NFATT);
|
|
|
|
const TRectype & doc = cache().get(LF_DOC, key);
|
|
|
|
if (!doc.empty())
|
|
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);
|
|
cn.complete_num(nf, numdoc_to_search);
|
|
}
|
|
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')
|
|
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 << TR("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();
|
|
long numreg = head.get_long(MOV_NUMREG);
|
|
|
|
if (_movimento->cg_items() >= 2) // Non ha senso un movimento di una riga sola
|
|
{
|
|
TRectype& head = _movimento->lfile().curr();
|
|
head.put(MOV_TOTDOC,_total_mov);
|
|
head.put(MOV_TOTDOCVAL,_total_mov_val);
|
|
|
|
const long orig_numreg = numreg;
|
|
while (_movimento->write() == _isreinsert)
|
|
head.put(MOV_NUMREG,++numreg);
|
|
if (_movimento->status() != NOERR)
|
|
{
|
|
error_box(FR("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(FR("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, int level)
|
|
{
|
|
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 (level > 0)
|
|
{
|
|
const int rata = row.get_int(REFF_NRATA);
|
|
str.format("%04d|%s|%04d|%04d", anno, (const char*)part, riga, rata);
|
|
|
|
if (level > 1)
|
|
{ // Devo fare in modo che le fatture precedano le note doi credito nell'array delle righe effetto
|
|
int tipo = 2;
|
|
if (row.get_real(REFF_IMPORTO) <= ZERO)
|
|
tipo = 1; // Nota di credito
|
|
str << '|' << tipo;
|
|
}
|
|
}
|
|
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, 2);
|
|
build_eff_key(r2, s2, 2);
|
|
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, 1);
|
|
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 TString& cc = distinta.tipocf() == 'F' ? _cod_caus_pag : _cod_caus;
|
|
_caus = new TCausale(cc, _data_op.year());
|
|
if (!_caus->ok())
|
|
{
|
|
_error = generic_error;
|
|
error_box(FR("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, 0);
|
|
|
|
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) // scrive il movimento residuo ...
|
|
{
|
|
if (customers.items() > 0)
|
|
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, TR("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)
|
|
message_box(FR("Totale distinte contabilizzate: %ld"),_total_bills);
|
|
}
|
|
|
|
int ef0800 (int argc, char* argv[])
|
|
{
|
|
TContabilizzazione_effetti_app a;
|
|
a.run(argc,argv,TR("Contabilizzazione effetti"));
|
|
return TRUE;
|
|
}
|