campo-sirio/ve/ve6300.cpp
angelo 15c5556fdb Correzioni per funzionare la 97_03
git-svn-id: svn://10.65.10.50/trunk@4781 c028cbd2-c16b-5b4b-a496-9718f37d4682
1997-06-28 08:52:33 +00:00

996 lines
35 KiB
C++
Executable File

// ve6300.cpp: programma di generazione effetti
// Muliebrica parodia...
// Il cavo delirante che irrompe nel silenzio dell'apogeo
// * * * * * * *
// *
// _ _______ _____________ ___================
// _I_I___oo_____ii__| |_|| | | \ | |O| |_| |_|
// | | - - | I | | | L M S | | | |
// _|___|________|____ I____|_|=|_____________|=II=|__|_|_____________
// I=| o (_)--(_)--(_)--(_) O--O O-O +++++ O-O \--/ ()==() ++++
//=======================================================================
//
//
// ____||____============____||___ ___===============================
// /__| OOOOOOOOOOOOO [_] | | |[]| [_] [_] [_] [_]
// / S N C F | | | |
// \________________________________|_ii_|__|__|___________________________
// ()==() === ++++ === ()==() ()==() +++ +++ ++++++++
//=========================================================================
//
// Have you ever heard MK ?
#include <applicat.h>
#include <relation.h>
#include <tabutil.h>
#include <mask.h>
#include <sheet.h>
#include <urldefid.h>
#include <progind.h>
#include <modaut.h>
#include <doc.h>
#include <rdoc.h>
#include <effetti.h>
#include <reffetti.h>
#include "../cg/cgsaldac.h"
#include "../ef/ef0101.h"
#include "velib.h"
#include "sconti.h"
#include "ve6300a.h"
// Enum di possibili errori
enum error_type {
no_error,
elaboration_error,
nr_doc_error,
chg_stat_error,
datadoc_error,
codpag_error,
scadenze_error,
write_error,
generic_error
};
// TGenerazioneEffetti_app
// Applicazione di generazione effetti
class TGenerazioneEffetti_app : public TApplication
{
TString16 _cod_el; // codice elaborazione immesso
TDate _data_reg; // data di registrazione immessa
TDate _data_ini; // data di inizio intervallo
TDate _data_fine; // data di fine intervallo
bool _raggruppa; // se TRUE raggruppa gli effetti secondo i criteri
TMask *_msk; // maschera di selezione dati
TRelation *_clifo; // relazione dei clienti e fornitori + cfven
TLocalisamfile *_docfile, // file dei documenti (per far funzionare TDocumento)
*_rdocfile, // file delle righe documento (per far funzionare TDocumento)
*_efffile, // file effetti
*_refffile, // file righe di effetti
*_cessfile, // file righe di cessionari
*_occas, // file degli occasionali
*_tab; // tabella di ditta
TTable *_cpg; // tabella condizioni di pagamento
TDocumento *_doc; // documento corrente
TCond_vendita *_condv; // Condizioni di vendita
// TCliFor *_clifor; // Cliente
TPagamento *_pagamento; // pagamento corrente, ricalcolato prima di scrivere le scadenze
TBit_array _valid_array; // array dei tipi di pagamento validi per la generazione di effetti
TArray_sheet *_num_sheet; // Array sheet selezionabile dei codici numerazione
TString_array _tipi_doc; // Array di stringhe contenente i tipi documenti da elaborare
TArray _effetti_array;//Array di effetti (TEffetto) da scrivere
TAssoc_array _group_array; // Assoc_array dei documenti da raggruppare. La chiave di ogni elemento
// e composta dagli stessi criteri di raggruppamento (vedi sotto)
// Ogni elemento e una TToken_string. Ogni elemento della TToken_string contiene
// la chiave per identificare il documento che fa parte di quel raggruppamento
error_type _error; // Errore rilevato durante l'elaborazione
long _total_bills; // Totale effetti generati
bool _can_write; // se TRUE e' abilitata la scrittura. Non appena rileva un errore rimane a FALSE for this instance
char _final_doc_status; // Valore per lo stato finale del documento
// Flags di raggruppamento opzionali (%ELD->S1):
bool _group_by_date, // raggruppa per data di scadenza
_group_by_sosp, // raggruppa per flag sosp. d'imposta
_group_by_change, // raggruppa per cambio
_group_by_pag, // raggruppa per cond. di pagamento
_group_by_bank, // raggruppa per banca (ABI-CAB)
_group_by_type, // raggruppa per tipo di documento
_group_by_num, // raggruppa per cod. numerazione
_group_by_agent; // raggruppa per agente
protected: // TApplication
// Cambia lo stato del documento
error_type change_doc_status();
// Coontrolla se lo stato ed il tipo del documento sono validi e rispettano la selezione
bool doc_tipo_stato_ok();
// Visualizza l'ultimo errore rilevato
void display_error();
// Genera l'effetto
void generate_bill();
// Genera gli effetti
void generate();
// Le 4 seguenti non hanno bisogno di commenti
virtual bool menu(MENU_TAG mt);
virtual bool create();
virtual bool destroy();
// Handler del codice elaborazione differita
static bool handle_cod_eld(TMask_field& f, KEY k);
// Handler dell'intervallo di date
static bool handle_data_range(TMask_field& f, KEY k);
// Handler del pulsante di selezione codici numerazione
static bool handle_select(TMask_field& f, KEY k);
// Ritorna il TArray_sheet contenente le selezioni sui codici numerazione
TArray_sheet* get_num_sheet() const { return _num_sheet; }
// Costruisce lo sheet dei codici numerazione
void build_num_sheet();
// Restituisce TRUE se il tipo di pagamento passato e' valido per generare l'effetto
bool valid_type(int tipo_pag) const ;
// Aggiunge il documento corrente alla lista dei documenti raggruppabili
void add_to_group_list();
// Costruisce la stringa chiave per raggruppamento
void build_group_key(TString& key);
// Costruisce la stringa chiave per documento
void build_doc_key(TToken_string& key);
// Setta i flags di raggruppamento opzionali in base alla tabella
void set_options();
// Effettua il raggruppamento vero e proprio degli effetti (solo se ci sono elementi nell'assoc_array
void group_bills();
// Istanzia il pagamento corrente
void calc_pagamento(TString16& codpag, const real& totale_fatt, TString16& data, const bool valuta, const real& change);
// Scrive i record array degli effetti raggruppati
error_type write_groups();
// Cambia lo stato dei gruppi di documenti raggruppati in effetti
error_type change_group_status();
public:
// Verifica se non ci sono stati errori
bool good() const { return _error == no_error;}
TGenerazioneEffetti_app() {_msk = NULL; _num_sheet = NULL;}
virtual ~TGenerazioneEffetti_app() { }
};
inline TGenerazioneEffetti_app& app() { return (TGenerazioneEffetti_app&) main_app(); }
bool TGenerazioneEffetti_app::handle_data_range(TMask_field& f, KEY k)
{
if (k==K_ENTER && f.dirty())
{
TMask& m = f.mask();
TDate da(m.get_date(F_DATA_INI));
TDate a(m.get_date(F_DATA_FIN));
//m.field(F_DATA_REG).set_dirty();
//if (a == botime || da == botime) return TRUE;
if (a < da)
{
f.error_box("La data di inizio deve essere minore della data di fine.");
return FALSE;
}
//if ((a - da) > 15)
//{
// f.error_box("L'intervallo tra le date non puo' eccedere i 15 giorni.");
// return FALSE;
//}
}
return TRUE;
}
bool TGenerazioneEffetti_app::handle_cod_eld(TMask_field& f, KEY k)
{
if (f.to_check(k) && k == K_TAB) // se e' cambiato ricostruisce anche lo sheet dei codici numerazione
{
app()._cod_el = f.get(); // aggiorna il codice elaborazione per la build_num_sheet()
f.mask().disable(DLG_OK);
app().build_num_sheet();
}
return TRUE;
}
bool TGenerazioneEffetti_app::handle_select(TMask_field& f, KEY k)
{
if (k == K_SPACE)
{
TMask& m = f.mask();
TArray_sheet* s = app().get_num_sheet();
if (s->run())
{
if (s->checked() != 0) // Hai selezionato qualcosa ?
m.enable(DLG_OK); // allora abilita il pulsante di conferma
else
m.disable(DLG_OK);
}
}
return TRUE;
}
void TGenerazioneEffetti_app::build_num_sheet()
{
_num_sheet->destroy();
TTable eld("%ELD");
TTable num("%NUM");
TString s1,s2,s3;
TString16 tipon1,tipon2,tipon3,tipon4,tipon5; // tipi documento validi per la numerazione
long pos;
eld.put("CODTAB",_cod_el);
if (eld.read() == NOERR)
{
TToken_string t;
s1.format("%-20s",(const char*)eld.get("S2"));
s3 = eld.get("S7");
_final_doc_status = eld.get("S4")[0];
for (int i=0;i<5;i++)
{
t = s1.mid(i*4,4); // Tipo documento
if (t.trim().empty()) break;
t.add(s3.mid(i,1)); // Stato iniziale
_tipi_doc.add(t); // Aggiunge questo tipo documento alla lista
}
for (pos=0,num.first();num.good();num.next(),pos++) // scorre tutte le numerazioni possibili
{
TToken_string t;
t.add(" ");
t.add(num.get("CODTAB"));
t.add(num.get("S0"));
_num_sheet->add(t);
s2 = num.get("S2"); // reperisce i tipi documento validi per questa numerazione
tipon1 = s2.mid(0,4);
tipon2 = s2.mid(4,4);
tipon3 = s2.mid(8,4);
tipon4 = s2.mid(12,4);
tipon5 = s2.mid(16,4);
const int n1 = s1.find(tipon1);
const int n2 = s1.find(tipon2);
const int n3 = s1.find(tipon3);
const int n4 = s1.find(tipon4);
const int n5 = s1.find(tipon5);
if ((tipon1.empty() || n1<0) && (tipon2.empty() || n2<0) &&
(tipon3.empty() || n3<0) && (tipon4.empty() || n4<0) &&
(tipon5.empty() || n5<0))
_num_sheet->disable_row(pos);
else
_num_sheet->enable_row(pos);
}
}
}
bool TGenerazioneEffetti_app::valid_type(int pag) const
{
return _valid_array[pag];
}
bool TGenerazioneEffetti_app::create()
{
TApplication::create();
if (!has_module(EFAUT))
{
error_box("Impossibile eseguire il programma se il modulo Effetti non e' abilitato");
return FALSE;
}
_error = no_error;
_can_write = TRUE;
_pagamento = NULL;
_msk = new TMask("ve6300a");
_msk->set_handler(F_CODICE_ELAB,handle_cod_eld);
_msk->set_handler(F_DATA_INI,handle_data_range);
_msk->set_handler(F_DATA_FIN,handle_data_range);
_msk->set_handler(DLG_USER,handle_select);
_num_sheet = new TArray_sheet(-1,-1,-4,-4,"Codici numerazione",
"@1|Cod. numerazione|Descrizione@50");
_docfile = new TLocalisamfile(LF_DOC);
_rdocfile = new TLocalisamfile(LF_RIGHEDOC);
_efffile = new TLocalisamfile(LF_EFFETTI);
_refffile = new TLocalisamfile(LF_REFFETTI);
_cessfile = new TLocalisamfile(LF_CESS);
_occas = new TLocalisamfile(LF_OCCAS);
// _clifor = new TCliFor();
// _condv = new TCond_vendita(_clifor);
_cpg = new TTable("%CPG");
_tab = new TLocalisamfile(LF_TAB);
_clifo = new TRelation(LF_CLIFO);
_clifo->add(LF_CFVEN,"TIPOCF=TIPOCF|CODCF=CODCF");
_condv = new TCond_vendita(NULL);
_doc = new TDocumento();
_condv->set_clifo(&_doc->clifor());
_doc->set_condv(_condv);
// Settaggio dell'array dei tipi documento che possono generare effetti
_valid_array.set(2); // tratta
_valid_array.set(3); // riba
_valid_array.set(5); // paghero'
_valid_array.set(7); // tratta accettata
_valid_array.set(8); // rapporti interbancari diretti (rid)
_valid_array.reset(9); // bonifici
dispatch_e_menu(BAR_ITEM(1));
return TRUE;
}
bool TGenerazioneEffetti_app::destroy()
{
if (_msk) delete _msk;
if (_num_sheet) delete _num_sheet;
if (_docfile) delete _docfile;
if (_rdocfile) delete _rdocfile;
if (_efffile) delete _efffile;
if (_refffile) delete _refffile;
if (_cessfile) delete _cessfile;
if (_occas) delete _occas;
if (_doc) delete _doc;
if (_cpg) delete _cpg;
if (_tab) delete _tab;
if (_clifo) delete _clifo;
return TApplication::destroy();
}
bool TGenerazioneEffetti_app::menu(MENU_TAG mt)
{
while (_msk->run() == K_ENTER)
{
_cod_el = _msk->get(F_CODICE_ELAB);
_data_ini = _msk->get_date(F_DATA_INI);
_data_fine = _msk->get_date(F_DATA_FIN);
_raggruppa = _msk->get_bool(F_RAGGRUPPA);
generate();
}
return FALSE;
}
bool TGenerazioneEffetti_app::doc_tipo_stato_ok()
// Verifica che il tipo documento corrente esista tra i tipi previsti dalla elaborazione
// differita selezionata
{
const int items = _tipi_doc.items();
bool found = FALSE;
const TString16 tipo(_doc->tipo().codice());
const char stato = _doc->stato();
for (int i=0;i<items && !found;i++)
{
TToken_string& t = _tipi_doc.row(i);
const TString16 tipox(t.get(0));
const char statox = t.get(1)[0];
if (tipo == tipox && stato == statox)
found = TRUE;
}
return found;
}
error_type TGenerazioneEffetti_app::change_doc_status()
// Cambia lo stato del documento
{
_doc->stato(_final_doc_status);
if (_doc->head().rewrite(*_docfile) != NOERR)
_error = chg_stat_error;
return _error;
}
error_type TGenerazioneEffetti_app::change_group_status()
// Cambia lo stato dei documenti raggruppati
{
const int items = _group_array.items();
if (items > 0)
{
_error = no_error;
TToken_string * group_element;
int i=0;
// Ciclo sugli elementi dell'assoc_array
for (group_element = (TToken_string *) _group_array.first_item(); group_element != NULL && i < items; i++,group_element = (TToken_string*)_group_array.succ_item())
{
group_element->restart();
const int doc_items = group_element->items();
for (int j=0;j<doc_items;j++)
{
TToken_string t(group_element->get(j),'$');
char provv = t.get_char(0);
int anno = t.get_int(1);
TString codnum(t.get(2));
long numdoc = t.get_long(3);
_docfile->put(DOC_PROVV,provv);
_docfile->put(DOC_ANNO,anno);
_docfile->put(DOC_CODNUM,codnum);
_docfile->put(DOC_NDOC,numdoc);
if (_docfile->read() == NOERR) // Legge il documento
{
_docfile->put(DOC_STATO,_final_doc_status);
_docfile->rewrite();
}
}
}
}
return _error;
}
void TGenerazioneEffetti_app::display_error()
{
TString msg;
TString numerazione = _doc->numerazione();
const long numero = _doc->numero();
switch (_error)
{
case elaboration_error:
msg.format("Il documento %s/%ld non rientra tra i tipi documento validi per l'elaborazione."
"Verificare i tipi documento ed il loro stato iniziale sul codice elaborazione inserito.",(const char*)numerazione,numero);
break;
case nr_doc_error:
msg.format("Rilevato un numero di documento errato contabilizzando il documento %s/%ld."
"Verificare il numero documento e il codice numerazione inseriti in tabella.",(const char*)numerazione,numero);
break;
case chg_stat_error:
msg.format("Rilevato un errore cambiando lo stato al documento %s/%ld."
"Verificare l'integrita' del file documenti.",(const char*)numerazione,numero);
break;
case datadoc_error:
msg.format("Rilevato una data documento vuota relativamente al documento %s/%ld."
"Verificare l'informazione inserita.",(const char*)numerazione,numero);
break;
case codpag_error:
msg.format("Rilevato un codice pagamento non esistente relativamente al documento %s/%ld."
"Verificare l'esistenza del codice pagamento inserito.",(const char*)numerazione,numero);
break;
case scadenze_error:
msg.format("Calcolate 0 scadenze relativamente al documento %s/%ld."
"Verificare la correttezza del codice pagamento inserito.",(const char*)numerazione,numero);
break;
case write_error:
if (_efffile->status() != NOERR)
msg.format("Si e' verificato l' errore %d in scrittura sul file effetti relativamente al documento %s/%ld"
"Verificare la consistenza del file.",_efffile->status(),(const char*)numerazione,numero);
else
msg.format("Si e' verificato l' errore %d in scrittura sul file righe effetti relativamente al documento %s/%ld"
"Verificare la consistenza del file.",_refffile->status(),(const char*)numerazione,numero);
break;
default:
msg.format("E' stato rilevato un errore generico contabilizzando il documento %s/%ld.",
(const char*)numerazione,numero);
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.
}
// Criteri di raggruppamento effetti.
// Un documento puo' essere raggruppato con i seguenti criteri:
// - flag di raggruppamento effetti a TRUE (obbligatorio)
// - cliente (obbligatorio)
// - valuta (obbligatorio)
// - data scadenza (opzionale)
// - flag di sosp. d'imposta (opzionale)
// - cambio valuta (opzionale)
// - cond di pagamento (opzionale)
// - banca (opzionale)
// - tipo doc. (opzionale)
// - cod. numerazione (opzionale)
// - agente (opzionale)
// I parametri opzionali sono decisi nella tabella elaborazioni
// Spiegazione del raggruppamento:
// Il raggruppamento di documenti diversi in uno stesso effetto consiste nella creazione
// di piu' righe dello stesso effetto.
// Ad esempio supponiamo di avere il cliente 10 con 4 fatture ognuna con condizioni di pagamento diverse
// la fattura 1 e' suddivisa in 2 rate (10.000 + 30.000)
// la fattura 2 e' suddivisa in 4 rate (15.000 + 20.000 + 25.000 + 30.000)
// la fattura 3 e' suddivisa in 5 rate (20.000 + 40.000 + 80.000 + 160.000 + 320.000)
// la fattura 4 e' suddivisa in 3 rate (50.000 + 100.000 + 150.000)
// Il numero di effetti generati equivale al massimo numero di rate (5 in questo caso)
// quindi avremo 5 effetti:
// il primo avra' 4 righe (prima rata di tutte le fatture)
// il secondo avra' 4 righe (seconda rata di tutte le fatture)
// il terzo avra' 3 righe (terza rata delle fatture 2,3,4)
// il quarto avra' 2 righe (quarta rata delle fatture 2 e 3)
// il quinto avra' 1 riga (quinta rata della fattura 3)
// La testata di ogni effetto conterra' il totale (somma) dei singoli importi delle righe
// ovvero:
// tot. primo effetto: 95.000
// tot. secondo effetto: 190.000
// tot. terzo effetto: 255.000
// tot. quarto effetto: 190.000
// tot. quinto effetto: 320.000
// I dati della testata (soprattutto la data di scadenza) di ogni effetto vengono presi dal
// primo documento valido per la generazione dell'effetto corrente:
// per i primi due effetti vale la fattura 1
// per gli effetti 3 e 4 vale la fattura 2
// per l'effetto 5 vale la fattura 3.
// Questo e' quanto ho appreso (Hope I'm right...) ;-)
void TGenerazioneEffetti_app::add_to_group_list()
{
TString key;
TToken_string t("",'$');
build_group_key(key);
build_doc_key(t);
const bool is_key = _group_array.is_key(key);
TToken_string tt(is_key ? (TToken_string&) _group_array[key]: "");
tt.add(t);
_group_array.add(key,tt, is_key ? TRUE : FALSE);
}
void TGenerazioneEffetti_app::build_group_key(TString& key)
{
long cli = _doc->get_long(DOC_CODCF);
TString16 val(_doc->get(DOC_CODVAL));
// campi obbligatori
key.format("%7ld%3s",cli,(const char*)val);
// campi opzionali
if (_group_by_date)
{
TString16 d(_doc->get(DOC_DATAINSC));
if (d.empty())
d = _doc->get(DOC_DATADOC);
key << d;
}
// Qual'e' il flag di sospensione d'imposta del documento ??
// if (_group_by_sosp)
// key << _doc->get(DOC_????);
if (_group_by_change)
key << _doc->get(DOC_CAMBIO);
if (_group_by_pag)
key << _doc->get(DOC_CODPAG);
if (_group_by_bank)
{
key << _doc->get(DOC_CODABIA); // banca cliente
key << _doc->get(DOC_CODCABA);
}
if (_group_by_type)
key << _doc->get(DOC_TIPODOC);
if (_group_by_num)
key << _doc->get(DOC_CODNUM);
if (_group_by_agent)
key << _doc->get(DOC_CODAG);
}
void TGenerazioneEffetti_app::build_doc_key(TToken_string& key)
{
key.add(_doc->get(DOC_PROVV));
key.add(_doc->get(DOC_ANNO));
key.add(_doc->get(DOC_CODNUM));
key.add(_doc->get(DOC_NDOC));
}
void TGenerazioneEffetti_app::set_options()
{
TTable eld("%ELD");
eld.put("CODTAB",_cod_el);
if (eld.read() == NOERR)
{
TString s1;
s1.format("%-20s",(const char*)eld.get("S1")); // Forzo la sua lunghezza a 20 per evitare subscript errors
_group_by_date = s1[12] == 'X';
_group_by_sosp = s1[13] == 'X';
_group_by_change = s1[0] == 'X';
_group_by_pag = s1[4] == 'X';
_group_by_bank = s1[5] == 'X';
_group_by_type = s1[2] == 'X';
_group_by_num = s1[3] == 'X';
_group_by_agent = s1[7] == 'X';
}
}
void TGenerazioneEffetti_app::calc_pagamento(TString16& codpag,const real& totale_fatt, TString16& data, const bool valuta, const real& change)
{
_pagamento = new TPagamento(codpag, data);
real totspese = _doc->spese();
real totimposte = _doc->imposta();
real totimponibili = totale_fatt - totimposte - totspese;
if (valuta)
{
real val1 = totimponibili * change;
real val2 = totimposte * change;
real val3 = totspese * change;
_pagamento->set_total_valuta( totimponibili, totimposte, totspese, change, val1, val2 ,val3);
}
else
_pagamento->set_total( totimponibili, totimposte, totspese );
_pagamento->set_rate_auto( );
}
error_type TGenerazioneEffetti_app::write_groups()
{
const int items = _effetti_array.items();
int err = NOERR;
_error = no_error;
for (int i = 0; i<items && err == NOERR; i++) // scorre gli effetti generati e li scrive su file
{
TEffetto& effetto = (TEffetto&)_effetti_array[i];
err = effetto.write(*_efffile); // Pensa a tutto lui per rinumerare...
}
if (err != NOERR)
{
i--;
for (int j = 0; j<i; j++) // rimuove gli effetti raggruppati, per non lasciare documenti raggruppati parzialmente
{
TEffetto& effetto = (TEffetto&)_effetti_array[j];
// posso fare tranquillamente la remove, visto che la numerazione dell'effetto e' gia' stata effettuata
effetto.remove(*_efffile);
}
error_box("Errore %d nella scrittura gruppi di effetti. Nessun raggruppamento effettuato.",err);
}
return _error;
}
void TGenerazioneEffetti_app::generate_bill() // bill in inglese significa anche effetto eheheh ;-)
{
// That's my JOB!
// Ogni rata della fattura (si parla di effetti attivi per ora) genera 1 effetto.
// con almeno una riga.
// Ad es. Se ho una fattura suddivisa in 3 rate essa generera' 3 effetti con una riga.
// Nel caso si decida di raggruppare gli effetti (vedi criteri di raggruppamento)
// avro' un effetto con tante righe quante scadenze di fattura sono raggruppabili
// Le fatture possono generare effetti solo per i seguenti tipi di pagamento:
// 2 - Tratta
// 3 - Ri.Ba.
// 5 - Paghero'
// 7 - Tratta accettata
// 8 - Rapporti interbancari diretti
// Caso mai tale insieme risultasse incompleto od errato basta solo modificare l'enum posto all'inizio del programma
TString16 codpag(_doc->get(DOC_CODPAG));
_cpg->put("CODTAB",codpag);
if (_cpg->read()!= NOERR)
{
_error = codpag_error;
return;
}
TString16 data(_doc->get(DOC_DATAINSC));
if (data.empty())
data = _doc->get(DOC_DATADOC);
const real totale_fatt = _doc->totale_doc(); // Importo in valuta
if (totale_fatt > ZERO)
{
const bool valuta = _doc->in_valuta();
const real change = _doc->cambio();
// calcolo delle scadenze
calc_pagamento(codpag,totale_fatt,data,valuta,change);
CHECK(_pagamento,"Failed to create a TPagamento");
const int numrate = _pagamento->n_rate( );
if (numrate < 1)
{
_error = scadenze_error;
return;
}
_efffile->last();
// Variabili per la scrittura dell'effetto
long nprog = _efffile->get_long(EFF_NPROGTR)+1;
const long codcf = _doc->get_long(DOC_CODCF);
const TString16 codval(_doc->get(DOC_CODVAL));
const TDate data_cambio = _doc->get_date(DOC_DATACAMBIO);
const long codabi = _doc->get_long(DOC_CODABIA);
const long codcab = _doc->get_long(DOC_CODCABA);
const TString16 provv(_doc->get(DOC_PROVV));
const int anno = _doc->get_int(DOC_ANNO);
const TString16 codnum(_doc->get(DOC_CODNUM));
const long nfatt = _doc->get_long(DOC_NDOC);
const TDate datafatt = _doc->get_date(DOC_DATADOC);
TRectype& effetto = _efffile->curr();
TRectype& reffetto = _refffile->curr();
real importo;
for (int i = 0; i < numrate && good(); i++)
{
if (valid_type(_pagamento->tipo_rata(i)))
{
effetto.zero();
reffetto.zero();
effetto.put(EFF_NPROGTR,nprog);
effetto.put(EFF_DATASCAD, _pagamento->data_rata(i));
effetto.put(EFF_TIPOPAG,_pagamento->tipo_rata(i));
effetto.put(EFF_ULTCLASS,_pagamento->ulc_rata(i));
effetto.put(EFF_CODCF, codcf);
effetto.put(EFF_CODVAL, codval);
if (valuta)
{
effetto.put(EFF_CAMBIO, change);
effetto.put(EFF_DATACAMBIO,data_cambio);
}
effetto.put(EFF_CODABI,codabi);
effetto.put(EFF_CODCAB,codcab);
effetto.put(EFF_EFFCOMP,TRUE);
if (i == numrate - 1) effetto.put(EFF_ULTRATA,TRUE);
// Put sulla riga dell'effetto
reffetto.put(REFF_NPROGTR,nprog);
reffetto.put(REFF_NRIGATR,1);
reffetto.put(REFF_DATAFATT, datafatt);
reffetto.put(REFF_NRATA,i+1);
reffetto.put(REFF_PROVV,provv);
reffetto.put(REFF_ANNODOC,anno);
reffetto.put(REFF_CODNUM,codnum);
reffetto.put(REFF_NFATT,nfatt);
importo = _pagamento->importo_rata(i,FALSE);
effetto.put(EFF_IMPORTO,importo);
reffetto.put(REFF_IMPFATT,totale_fatt);
reffetto.put(REFF_IMPORTO,importo);
if (valuta)
{
importo = _pagamento->importo_rata(i,TRUE); // Importo in valuta
real totfatlit = totale_fatt*change; //Not sure about this...
effetto.put(EFF_IMPORTOVAL,importo);
reffetto.put(REFF_IMPFATTVAL,totale_fatt);
reffetto.put(REFF_IMPFATT,totfatlit);
reffetto.put(REFF_IMPORTOVAL,importo);
}
if (_efffile->write() == NOERR && _refffile->write() == NOERR)
{
_total_bills++;
nprog++;
}
else _error = write_error;
}
}
}
if (_pagamento)
{
delete _pagamento;
_pagamento = NULL;
}
if (good() && _can_write)
change_doc_status();
}
void TGenerazioneEffetti_app::group_bills()
{
// Bail out if there aren't items...
_error = no_error;
const int items = _group_array.items();
if (items == 0) return;
int i=0,j,n,offset=0;
TString msg1,msg2;
TString16 codpag;
real imprata, imprataval, importo, importoval;
msg1 = "Raggruppamento effetti ";
msg1 << "dal ";
msg1 << _data_ini.string() << " al ";
msg1 << _data_fine.string();
#ifdef DBG
TProgind p(items,msg1,TRUE,TRUE,1);
#else
TProgind p(items,msg1,FALSE,TRUE,1);
#endif
TToken_string * group_element;
// Ciclo sugli elementi dell'assoc_array
for (group_element = (TToken_string *) _group_array.first_item(); group_element != NULL && i < items; i++,group_element = (TToken_string*)_group_array.succ_item())
{
#ifdef DBG
if (p.iscancelled()) break;
#endif
p.setstatus(i+1);
// Ciclo sui documenti da raggruppare
group_element->restart();
const int doc_items = group_element->items();
for (j=0;j<doc_items;j++)
{
#ifdef DBG
if (p.iscancelled()) break;
#endif
TToken_string t(group_element->get(j),'$');
char provv = t.get_char(0);
int anno = t.get_int(1);
TString codnum(t.get(2));
long numdoc = t.get_long(3);
if (_doc->read(provv,anno,codnum,numdoc) != NOERR) continue; // Legge il documento (giusto saltare e proseguire se non lo trova?)
msg2 = "Documento: ";
msg2 << codnum << "/" << numdoc;
xvt_statbar_set(msg2);
do_events();
// Ricalcola le scadenze
codpag = _doc->get(DOC_CODPAG);
_cpg->put("CODTAB",codpag);
if (_cpg->read()!= NOERR)
{
_error = codpag_error;
return;
}
TString16 data(_doc->get(DOC_DATAINSC));
if (data.empty())
data = _doc->get(DOC_DATADOC);
const real totale_fatt = _doc->totale_doc();
const bool valuta = _doc->in_valuta();
const real change = _doc->cambio();
const TDate datafatt = _doc->get_date(DOC_DATADOC);
calc_pagamento(codpag,totale_fatt,data,valuta,change);
CHECK(_pagamento,"Failed to create a TPagamento");
const int numrate = _pagamento->n_rate( );
if (numrate < 1)
{
_error = scadenze_error;
return;
}
// Scorre le scadenze
for (n = 1; n <= numrate && good(); n++)
{
// Se non esiste effetto n-esimo (corrisponde al numero di rata corrente+offset)
// lo genera con la relativa riga. Se esiste vi somma gli importi ed accoda la riga
const bool is_new = n+offset > _effetti_array.items();
if (is_new) // Nuovo effetto: crea effetto con i dati di questo documento (e' il primo che incontro nella scansione)
{
TEffetto effetto;
// Setta i dati della testata;
effetto.put(EFF_DATASCAD, _pagamento->data_rata(n-1));
effetto.put(EFF_TIPOPAG,_pagamento->tipo_rata(n-1));
effetto.put(EFF_ULTCLASS,_pagamento->ulc_rata(n-1));
effetto.put(EFF_CODCF, _doc->get_long(DOC_CODCF));
effetto.put(EFF_CODVAL, _doc->get(DOC_CODVAL));
effetto.put(EFF_CAMBIO, change);
effetto.put(EFF_DATACAMBIO,_doc->get_date(DOC_DATACAMBIO));
effetto.put(EFF_CODABI,_doc->get(DOC_CODABIA));
effetto.put(EFF_CODCAB,_doc->get(DOC_CODCABA));
effetto.put(EFF_EFFCOMP,TRUE);
_effetti_array.add(effetto);
}
// aggiorna totale effetto (testata)
TEffetto& effetto=(TEffetto&)_effetti_array[n+offset-1];
importo = effetto.get_real(EFF_IMPORTO);
imprata = _pagamento->importo_rata(n-1,FALSE);
importo += imprata;
effetto.put(EFF_IMPORTO,importo);
if (valuta)
{
importoval = effetto.get_real(EFF_IMPORTOVAL);
imprataval = _pagamento->importo_rata(n-1,TRUE);
importoval += imprataval;
effetto.put(EFF_IMPORTOVAL,importoval);
}
// Crea la nuova riga di questo effetto
const int rows = effetto.rows_r();
TRectype& riga = effetto.row_r(rows+1,TRUE);
// reffetto.put(REFF_NPROGTR,nprog);
riga.put(REFF_NRIGATR,rows+1);
riga.put(REFF_NRATA,n);
riga.put(REFF_DATAFATT, datafatt);
riga.put(REFF_PROVV,provv);
riga.put(REFF_ANNODOC,anno);
riga.put(REFF_CODNUM,codnum);
riga.put(REFF_NFATT,numdoc);
riga.put(REFF_IMPFATT,totale_fatt);
riga.put(REFF_IMPORTO,imprata);
if (valuta)
{
riga.put(REFF_IMPFATTVAL,totale_fatt);
real totfatlit = totale_fatt*change;
riga.put(REFF_IMPFATT,totfatlit);
riga.put(REFF_IMPORTOVAL,imprataval);
}
} // Ciclo sulle scadenze
if (_pagamento)
{
delete _pagamento;
_pagamento = NULL;
}
} // Ciclo sui documenti di questo gruppo
offset=_effetti_array.items();
} // Ciclo sui gruppi
// Cambia lo stato a tutti i documenti raggruppati
if (good())
if (write_groups() == no_error)
{
_total_bills += _effetti_array.items();
change_group_status();
}
}
void TGenerazioneEffetti_app::generate()
{
TRelation doc_rel(LF_DOC);
TRectype da(LF_DOC),a(LF_DOC);
const long items = _num_sheet->items();
int year_from = _data_ini.year();
int year_to = _data_fine.year();
TString16 codnum;
TString msg,filt_expr;
_total_bills = 0;
_group_array.destroy();
_effetti_array.destroy();
set_options();
da.put("DATADOC",_data_ini);
da.put("PROVV","D");
da.put("ANNO",year_from);
a.put("DATADOC",_data_fine);
a.put("PROVV","D");
a.put("ANNO",year_to);
for (long i=0L; i<items;i++) // Scorre per tutte le numerazioni dello sheet
if (_num_sheet->checked(i)) // Se la numerazione corrente e' stata selezionata
{ // istanzia un cursore per la numerazione corrente, con i limiti di data
codnum = _num_sheet->row(i).get(1);
filt_expr = "CODNUM=\"";
filt_expr << codnum << "\"";
TCursor doc_cur(&doc_rel,filt_expr,3,&da,&a);
const long cur_items = doc_cur.items(); // Scorre tutti i documenti che rientrano nell'intervallo selezionato
if (cur_items == 0)
{
warning_box("Non vi sono effetti da generare per il codice numerazione %s",(const char*)codnum);
continue;
}
msg = "Generazione effetti ";
msg << codnum << " dal ";
msg << _data_ini.string() << " al ";
msg << _data_fine.string();
#ifdef DBG
TProgind p(cur_items,msg,TRUE,TRUE,1);
#else
TProgind p(cur_items,msg,FALSE,TRUE,1);
#endif
long j = 0;
// Comportamento:
// - scorre i documenti della numerazione corrente.
// - se e' possibile generare subito l'effetto (tipo di pagamento valido,
// stato documento valido e non e' abilitato il raggruppamento) lo fa,
// altrimenti compone una lista dei documenti da raggruppare
// - alla fine del ciclo per numerazioni scorre la lista residua e genera gli
// effetti rimasti
#ifdef DBG
for (;j<cur_items && !p.iscancelled();j++)
#else
for (;j<cur_items;j++)
#endif
{
p.setstatus(j+1);
doc_cur = j;
if (_doc->read(doc_cur.curr()) != NOERR) continue;// legge il documento
if (codnum != _doc->get(DOC_CODNUM)) continue; // patch del cazzo
if (doc_tipo_stato_ok()) // controlla che il tipo documento e lo stato siano coerenti con la ELD selezionata
{
TPagamento & pag = _doc->pagamento();
if (pag.code().not_empty()) // && valid_type(pag.tipo_rata(0))) // il tipo di pagamento puo' generare effetti ?
{
const bool raggruppabile = _doc->get_bool(DOC_RAGGREFF);
if (!_raggruppa || (_raggruppa && !raggruppabile))
generate_bill();
else
add_to_group_list();
}
else
if (good() && _can_write)
change_doc_status();
}
// else
// {
// ATTENZIONE!: se non ha ancora cominciato a generare effetti, eventuali
// documenti con tipo o stato differenti vengono semplicemente scartati
// senza segnalare errori
// if (_total_bills > 0)
// _error = elaboration_error;
// }
if (!good())
display_error();
}
#ifdef DBG
if (p.iscancelled()) break;
#endif
}
// Effettua il raggruppamento di eventuali documenti rimasti
if (good())
group_bills();
// Mostra eventuali errori residui
if (!good())
display_error();
if (_total_bills > 0)
message_box("Totale effetti generati: %ld",_total_bills);
xvt_statbar_set("");
}
int ve6300 (int argc, char **argv)
{
TGenerazioneEffetti_app a;
a.run(argc,argv,"Generazione effetti");
return TRUE;
}