// ve6300.cpp. Composizione interattiva dei documenti. #include #include #include #include #include #include #include #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 è 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ù 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 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 */