431 lines
16 KiB
C++
Executable File
431 lines
16 KiB
C++
Executable File
// ve6300.cpp. Composizione interattiva dei documenti.
|
||
|
||
#include <config.h>
|
||
#include <application.h>
|
||
#include <mask.h>
|
||
#include <relation.h>
|
||
#include <urldefid.h>
|
||
#include <utility.h>
|
||
#include <tabutil.h>
|
||
|
||
#include "ve6retv.h"
|
||
#include "ve6300.h"
|
||
#include "ve6gen.h"
|
||
|
||
class TInterattivo_crea_doc : public TBatch_crea_doc
|
||
{
|
||
private:
|
||
virtual bool menu (MENU_TAG);
|
||
virtual bool create ();
|
||
virtual bool destroy();
|
||
|
||
// int set_vars(); // setta le variabili della classe
|
||
int componi_doc_finale(); // corpo del programma
|
||
static bool tipo_doc_handler (TMask_field&, KEY); // handler per il campo tipo doc. destinaz. della maschera
|
||
// static bool filterfunct(const TRelation*); // funzione per filtrare i documenti originali
|
||
|
||
int _rdoc; // numero di righe nel documento finale
|
||
public:
|
||
TInterattivo_crea_doc(void) {}
|
||
~TInterattivo_crea_doc() {}
|
||
};
|
||
|
||
inline TInterattivo_crea_doc& app() { return (TInterattivo_crea_doc&) main_app(); }
|
||
|
||
bool TInterattivo_crea_doc::create()
|
||
{
|
||
_interattivo = TRUE;
|
||
|
||
const int cargc = argc();
|
||
const char **vargv = argv();
|
||
|
||
if (cargc >= 2)
|
||
{
|
||
if (cargc < 5)
|
||
return error_box ("Numero di parametri insufficiente: chiave incompleta!");
|
||
|
||
if (cargc >= 5)
|
||
{
|
||
_codnum = vargv[2];
|
||
_anno = vargv[3];
|
||
_provv = vargv[4];
|
||
_ndoc = vargv[5];
|
||
_crea_doc = (cargc == 7);
|
||
}
|
||
|
||
if (cargc > 7)
|
||
message_box ("Sono presenti piu' di 6 argomenti sulla linea di comando: possibile errore");
|
||
}
|
||
|
||
dispatch_e_menu(BAR_ITEM(1));
|
||
return TRUE;
|
||
}
|
||
|
||
bool TInterattivo_crea_doc::destroy()
|
||
{
|
||
return TRUE;
|
||
}
|
||
|
||
bool TInterattivo_crea_doc::menu(MENU_TAG)
|
||
{
|
||
// if (errore_fatale (set_vars())) return FALSE;
|
||
if (errore_fatale (componi_doc_finale()))
|
||
return FALSE;
|
||
return TRUE;
|
||
}
|
||
|
||
/*
|
||
TInterattivo_crea_doc::set_vars()
|
||
{
|
||
TMask m("ve6300.uml");
|
||
|
||
m.set_handler (F_TIPODOCDES, tipo_doc_handler);
|
||
if (m.run()==K_ESC) return ESC_PRESSED;
|
||
_datadoc = m.get(F_DATADOC); // data da assegnare al documento da creare
|
||
_first_codcf = _last_codcf = m.get_long(F_CODCF); // codice cliente
|
||
_tipo_doc_des = m.get(F_TIPODOCDES); // tipo del documento da creare
|
||
_codnum = m.get(F_CODNUM); // codice numerazione per il documento da creare
|
||
_anno << _datadoc.year(); // anno fiscale del documento da creare
|
||
_provv = m.get(F_PROVV); // indica se il la numerazione _codnum e' provvisoria o definitiva
|
||
|
||
// cerca il record di ELD che corrisponde a _tipo_doc_des
|
||
// TRelation rel("ELD");
|
||
// TString16 filter ("S8==\"");
|
||
// filter << _tipo_doc_des << '"';
|
||
// TCursor curs(&rel, filter);
|
||
// if (curs.items()==0)
|
||
// {
|
||
// fatal_box (TString("Nessuna elaborazione genera documenti del tipo ") << _tipo_doc_des);
|
||
// return NO_ELABS;
|
||
// }
|
||
// else if (curs.items()>1)
|
||
// warning_box ("Trovate %d elaborazioni per la generazione dei documenti di tipo %s", curs.items(), (const char*)_tipo_doc_des);
|
||
//
|
||
// return 0;
|
||
}
|
||
*/
|
||
|
||
// handler per il tipo documento di destinazione
|
||
bool TInterattivo_crea_doc::tipo_doc_handler (TMask_field& field, KEY key)
|
||
{
|
||
if (key == K_TAB)
|
||
{
|
||
if (field.to_check(key))
|
||
{
|
||
TFixed_string tdd(field.get(),4); // tipo del documento destinazione selezionato
|
||
tdd.trim();
|
||
TTable t("%TIP");
|
||
t.zero();
|
||
t.put ("CODTAB", tdd); // cerca tipo del documento destinazione
|
||
t.read (_isgteq);
|
||
/* if (err = t.read (_isgteq)) // si posiziona sul record relativo al documento del tipo specificato
|
||
{
|
||
error_box ("TElaborazioni::run_mask() : errore di lettura %d da tab(TIP)", err);
|
||
return READ_ERROR;
|
||
}
|
||
*/
|
||
if (t.get ("CODTAB") != tdd) // verifica che il tipo di documento trovato sia quello richiesto
|
||
{
|
||
error_box ("TElaborazioni::run_mask() : non esiste il tipo documento %s in tab(TIP)", (const char *)tdd);
|
||
return DOC_TYPE_NOT_FOUND;
|
||
}
|
||
TFilename profilo(t.get ("S4")); // nome del profilo documento (nome del .ini associato al tipo documento originale)
|
||
profilo.ext("ini");
|
||
TConfig profilo_doc(profilo); // file di configurazione (ini) del documento
|
||
TString tipocf = (profilo_doc.get("TIPOCF", "MAIN"));
|
||
tipocf.cut(1);
|
||
field.mask().set(F_TIPOCF, tipocf);
|
||
}
|
||
}
|
||
|
||
TMask& mask = field.mask();
|
||
TFixed_string s(mask.get(F_TIPIDOC), 40);
|
||
if (key==K_ENTER || key==K_TAB)
|
||
return (s.find(field.get()) % 4) == 0; // per evitare che trovi "0010" in "00010002"
|
||
return TRUE;
|
||
}
|
||
|
||
int TInterattivo_crea_doc::componi_doc_finale()
|
||
{
|
||
int err; // errori ritornati dalle funzioni
|
||
// long n; // numero della fattura nella numerazione corrente
|
||
bool no_select = TRUE; // TRUE se non sono stati selezionati documenti dallo sheet
|
||
bool no_elab = TRUE; // TRUE se non ha ancora elaborato nessun documento
|
||
TLocalisamfile f(LF_DOC); // per gestire la testata dei documenti
|
||
TLocalisamfile rdoc(LF_RIGHEDOC); // per gestire le righe dei documenti
|
||
int current = 0; // chiave corrente
|
||
TRectype pilota (LF_DOC); // record per il documento pilota
|
||
TTable t("NUM"); // tabella numerazioni
|
||
TRectype tempr(LF_DOC); // record del documento originale che si sta elaborando
|
||
TRectype temprdoc (LF_RIGHEDOC); // record per trovare le righe dei documenti originale
|
||
// int nrdoc; // numero di righe scritte nella fattura
|
||
// bool end = FALSE; // true non ci sono piu' documenti originali da elaborare
|
||
bool altri; // TRUE se ci sono altri documenti da includere nella fattura
|
||
// se _crea_doc, il documento destinazione (testata) deve essere inizializzato
|
||
// con i valori del primo documento originale selezionato
|
||
bool primo_pilota = _crea_doc;
|
||
|
||
f.put ("CODNUM", _codnum); // la fattura va numerata in base alla codnum specificata in ELD
|
||
f.put ("ANNO", _anno); // imposta l'anno del documento
|
||
f.put ("PROVV", _provv); // imposta provv./def. del documento
|
||
f.put ("NDOC", _ndoc); // imposta il numero del documento
|
||
|
||
err = f.read(_isgteq); // cerca il documento
|
||
if (err) // guarda se si <20> verificato un errore
|
||
{
|
||
error_box ("Errore di lettura %d in doc, cercando il documento", err);
|
||
return READ_ERROR;
|
||
}
|
||
/* else if (_crea_doc) f.curr() = pilota; // tutti i campi della fattura sono uguali al documento pilota, tranne alcuni (impostati pi<70> sotto)
|
||
else {
|
||
// confronta f.curr() e pilota (se pilota ha dei campi diversi, segnalalo e chiedi conferma
|
||
}
|
||
*/
|
||
// }
|
||
_first_codcf = _last_codcf = f.get_long("CODCF"); // valori del campo CODCF dei records first e last, per potervi accedere dalla filterfunct()
|
||
_tipo_doc_des = f.get ("TIPODOC"); // imposta il tipo di documento
|
||
_stato_f_doc_f = f.get ("STATO"); // stato della fattura appena creata
|
||
|
||
TRelation rel (LF_DOC);
|
||
TString tdfilter(1024);
|
||
tdfilter =""; // non so se e' necessaria
|
||
#ifdef _TDD_IN_FILTER
|
||
// filtro costruito in base a tutti i tipi di doc. che hanno un ELD che li trasforma in _tipo_doc_des
|
||
tdfilter = td_ELD_to_filter(_tipo_doc_des);
|
||
#endif
|
||
|
||
TSorted_cursor curs (&rel, "NDOC", tdfilter); // lista i documenti ordinati per numero
|
||
curs.set_filterfunction (filterfunct);
|
||
|
||
// non dovrebbe servire : _raggruppa = TRUE;
|
||
_per_articolo = TRUE;
|
||
|
||
// Cursore per selezionare le testate dei documenti
|
||
if (curs.items() == 0) // se non ci sono bolle allo stato richiesto, indica errore
|
||
{
|
||
error_box ("Nessun documento da elaborare.");
|
||
return NO_ORG_DOCS;
|
||
}
|
||
curs.freeze(); // non perdere tempo a riaggiornarti
|
||
// curs=0; // comincia dal primo documento della lista
|
||
|
||
// scandaglia tutto curs e setta _processed tutti i doc. originali che non sono selezionati
|
||
TString80 Titolo("Documenti elaborabili che possono diventare ");
|
||
Titolo << _tipo_doc_des;
|
||
TCursor_sheet docs_sheet(&curs,
|
||
" |NDOC|TIPODOC|DATADOC|TIPOCF|CODCF|OCFPI",
|
||
Titolo,
|
||
"@1|Numero@7|Tipo@4|Data@10|C/F|Cod. cliente|CF o P.IVA@16");
|
||
|
||
docs_sheet.enable_check();
|
||
if (docs_sheet.run()==K_ESC) return ESC_PRESSED;
|
||
for (int i=0; i<docs_sheet.items(); i++)
|
||
if (!docs_sheet.checked(i))_processed.set(i);
|
||
else no_select = FALSE;
|
||
if (no_select)
|
||
{
|
||
error_box ("Nessun documento selezionato.");
|
||
return NO_ORG_DOCS;
|
||
}
|
||
|
||
// scandaglia tutto curs e torna con errore se un doc. originale non hanno la ELD
|
||
for (int l=0; l<curs.items();l++)
|
||
if (!_processed[l])
|
||
{
|
||
if ((err = esiste_ELD(curs,l,DONT_SET_PROCESSED))==ELAB_NOT_FOUND) return err;
|
||
TRectype &curr = curs.curr();
|
||
TConfig doc_config (getini(curr,err), "RAGGRUPPA"); // prende il .ini di curr
|
||
_stati_validi_doc_i = doc_config.get ("STATIVALIDI"); // stato iniziale del documento originale
|
||
if (!statovalido(curr))
|
||
{
|
||
error_box("Documento selezionato (tipo %s,numero %s) non e' in uno stato adatto all'elaborazione",
|
||
curr.get("TIPODOC"), curr.get("NDOC"));
|
||
return ERR_STATO_NON_VALIDO;
|
||
}
|
||
}
|
||
|
||
while (next_pilota(curs,pilota)) // ciclo di generazione fattura
|
||
// locka automaticamente il documento (pilota) che sta elaborando
|
||
{
|
||
// get_info(pilota);
|
||
//*****************************************************
|
||
//* questa sezione serve a CREARE il documento finale *
|
||
//*****************************************************
|
||
|
||
// imposta il numero per la fattura da creare
|
||
// inserisce il record di testata della fattura che va a creare
|
||
|
||
tempr = pilota; // il primo documento org. da elaborare <20> quello pilota
|
||
|
||
// qui inizia il ciclo per la creazione della fattura
|
||
// N.B.: appende ogni documento originale nella fattura
|
||
TRecord_array doc_destinazione (LF_RIGHEDOC, "NRIGA"); // array contenente le righe della fattura
|
||
TRectype r (LF_RIGHEDOC); // costruisce ed imposta la chiave per doc_destinazione
|
||
r.zero();
|
||
r.put ("CODNUM", _codnum);
|
||
r.put ("ANNO", _anno);
|
||
r.put ("PROVV", _provv);
|
||
r.put ("NDOC", _ndoc);
|
||
doc_destinazione.read(r);
|
||
// doc_destinazione.set_key(&r);
|
||
|
||
// legge tutte le fatture
|
||
do
|
||
{
|
||
// appende il documento originale al documento di destinazione
|
||
get_info(tempr);
|
||
bool raggr_parz = get_raggr_parz(tempr,err);
|
||
TString met = metodo(tempr);
|
||
// elab_righe restituisce TRUE solo se tutte le righe del documento originale
|
||
// sono state elaborate, quando cioe' il doc_destinazione deve cambiare stato
|
||
if (elab_righe(met,raggr_parz,tempr,doc_destinazione,temprdoc))
|
||
{
|
||
curs.file(LF_DOC).put ("STATO", _stato_f_doc_i); // aggiorna lo stato del documento originale
|
||
curs.file(LF_DOC).setkey(1);
|
||
if (err = curs.file(LF_DOC).rewrite())
|
||
{
|
||
error_box ("ve6200: Errore fatale: %d scrivendo sul file DOC", err);
|
||
return RECORD_WRITE_ERROR;
|
||
}
|
||
}
|
||
if (primo_pilota)
|
||
{
|
||
primo_pilota = FALSE;
|
||
f.curr() = tempr;
|
||
f.put ("CODNUM", _codnum);
|
||
f.put ("ANNO", _anno);
|
||
f.put ("PROVV", _provv);
|
||
f.put ("NDOC", _ndoc);
|
||
f.put ("TIPODOC", _tipo_doc_des); // reimposta il tipo di documento
|
||
f.put ("STATO", _stato_f_doc_f); // stato della fattura appena creata
|
||
// curs.file(LF_DOC).setkey(1);
|
||
if (err = f.rewrite())
|
||
{
|
||
error_box ("ve6200: Errore fatale: %d scrivendo sul file DOC", err);
|
||
return RECORD_WRITE_ERROR;
|
||
}
|
||
}
|
||
// unlocka il record del documento processato
|
||
curs.file(LF_DOC).setkey(2);
|
||
curs.unlock();
|
||
// indica che il documento e' stato processato
|
||
_processed.set(curs.pos());
|
||
// cerca il prossimo doc. org. da inserire. Se non ce ne sono piu', termina la generazione fattura
|
||
// se ce ne sono ancora, mette in tempr il record di doc del prossimo documento da agguungere
|
||
altri = search(pilota, tempr, curs);
|
||
}
|
||
while (altri); // fine del ciclo che raggruppa le bolle dentro una fattura
|
||
|
||
// controlla se deve raggruppare le righe per codice articolo
|
||
if (_per_articolo && (doc_destinazione.rows() > 1)) // se deve raggr. e ci sono almeno 2 righe
|
||
raggruppa_righe (doc_destinazione);
|
||
|
||
// salva la fattura creata
|
||
if (err = doc_destinazione.write())
|
||
{
|
||
error_box ("Errore nella scrittura del doc. destinazione. err = %d", err);
|
||
return RECORD_WRITE_ERROR;
|
||
}
|
||
|
||
no_elab = FALSE; // ha elaborato almeno un documento
|
||
|
||
// cerca il prossimo documeto pilota
|
||
}; // finche' i documenti non finiscono
|
||
if (no_elab) // se non ci sono bolle allo stato richiesto, indica errore
|
||
{
|
||
error_box ("Nessun documento elaborato.");
|
||
return NO_ORG_DOCS;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
int ve6300 (int argc, char** argv)
|
||
{
|
||
TInterattivo_crea_doc a;
|
||
a.run (argc, argv, "Composizione documenti");
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
TPerson p ("MATTEO LIGABUE");
|
||
p.send_message(
|
||
"DISCLAIMER: se leggerai questo pseudocodice e lo troverai childish, sappi che dopo la prima
|
||
stesura non l'ho piu' modificato, quindi questa e' l'idea che inizialmente avevo del programma
|
||
di composizione interattiva.");
|
||
p.bye();
|
||
|
||
- il prg per ora fa:
|
||
|
||
a) runna una maschera in cui chiede:
|
||
a1) il codice di numerazione del doc da comporre (+PROVV)
|
||
a2) il tipo di documento da comporre
|
||
a3) la data (AUTOMAGIC)
|
||
a4) TIPOCF/CODCF del doc da comporre (e degli originali da selezionare)
|
||
a5) tipo di documento originale (da TOGLIERE !!!)
|
||
|
||
b) runna un TCursor_Sheet con i documenti individuati da scegliere ed elaborare
|
||
|
||
c) runna un TInterattivo_sheet (TCursor_Sheet) con le singole righe da elaborare (selezionabili)
|
||
|
||
d) se la relativa tabella ELD permette l'evasione di parti di riga,
|
||
a1) mostrare il TCursor_sheet o TSpreadsheet (TSheet_field con maschera ve6301.uml)
|
||
a2) che possa trattare l'evasione parziale (TCursor_sheet -> con un campo number staccato dallo sheet)
|
||
a3) oppure il TSpreadsheet (TSheet_field) con tutte le colonne disabilitate, tranne la QTA_DA_EVADERE
|
||
|
||
il programma deve ancora:
|
||
|
||
a) passare la trasformazione al ve6200, che nella sua parte centrale (elaborazione del singolo doc.)
|
||
deve avere la eventuale selezione (da richiedersi in base ad un flag che ve6200 e ve6300 devono
|
||
settare rispettivamente a FALSE e TRUE, alla propria entrata) delle singole righe....
|
||
aggiornare la qtaevase dei singoli sorgenti...
|
||
lo stato del documento varia solo con la completa evasione delle righe !!!
|
||
|
||
... da continuare ...
|
||
|
||
- controllare lo stato dei documenti originali
|
||
|
||
-*chiama una funzione che runna la maschera e copia i nomi dei campi in variabili private
|
||
-*chiama una funzione che trova il record di ELD relativo al documento destinazione specificato
|
||
e setta le rimanenti variabili private
|
||
-*chiama una funzione che trova i documenti (testate) validi. Usare un TSorted_cursor od un
|
||
TRecord_array
|
||
|
||
componi la testata del documento originale con le variabili private (non metterci NDOC)
|
||
while l'utente non preme il button "Salva" per salvare il documento composto
|
||
se l'utente vuole inserire un documento dalla lista allora
|
||
mostra la lista
|
||
per ogni documento selezionato
|
||
se il flag "raggruppa unito" e' true, allora // caso doc. orig = BOLLE
|
||
fagli vedere le righe
|
||
attendi che prema un button
|
||
se preme ok aggiungi le righe al documento finale
|
||
end se ru=TRUE
|
||
altrimenti // caso doc. orig = ORDINI
|
||
fagli vedere le righe
|
||
attendi che selezioni le righe (possibilita' di selezionarle tutte)
|
||
//
|
||
usare un TBit_array per indicare se una riga va evasa tutta oppure se ne e' stata specificata una parte
|
||
settare a TRUE tutto il TBit_array; ??????????
|
||
se doubleclicka una riga
|
||
chiedigli la quantita' da evadere (puo' essere inferiore alla quantita' ordinata su quella riga)
|
||
scrivi nel documento originale la quantita' evasa
|
||
setta il TBit_array per indicare che nella bolla deve essere scritta la quantita' evasa
|
||
end se dblclk riga
|
||
//
|
||
...preferisco usare un TArray delle quantita' evase
|
||
|
||
end altrimenti (ru=FALSE)
|
||
end per ogni documento selezionato
|
||
end se seleziona dei documenti
|
||
altrimenti // vuole aggiungere delle righe
|
||
leggi i campi della riga (settando automaticamente codnum, ecc.)
|
||
metti la riga letta nel documento finale
|
||
end altrimenti (inserimento righe)
|
||
end
|
||
|
||
scrivi NDOC nella testata del documento
|
||
scrivi la testata del documento
|
||
salva il documento destinazione
|
||
end
|
||
*/
|