#include #ifndef __CHECKS_H #include #endif #ifndef __TABUTIL_H #include #endif #ifndef __BRWAPP_H #include #endif #ifndef __RELAPP_H #include #endif #ifndef __CONFIG_H #include #endif #ifndef __LFFILES_H #include #endif #ifndef __DEFMASK_H #include "defmask.h" #endif #ifndef __VEUML_H #include "veuml.h" #endif #ifndef __VEUML1_H #include "veuml1.h" #endif #ifndef __SHEET_H #include #endif #ifndef __REAL_H #include #endif #ifndef __MSKSHEET_H #include #endif #ifndef __VE0100_H #include "ve0100.h" #endif #ifndef __VE0100C_H #include "ve0100c.h" #endif #ifndef __VE0100D_H #include "ve0100d.h" #endif #ifndef __TCLIFOR_H #include "tclifor.h" #endif #ifndef __VE1000O_H #include "ve1000o.h" #endif #ifndef __TMASKVEN_H #include "tmaskven.h" #endif #ifndef __EXECP_H #include "execp.h" #endif #ifndef __SCONTI_H #include "sconti.h" #endif #define CHANGE_MESSAGE "Sono state effettuate modifiche alla configurazione.\nPrima di eseguire la gestione documenti occorrerà rigenerare le maschere.\nDesideri farlo ora ?" // Numero di colonne presenti sullo sheet totale #define MAX_COLUMNS 22 #define F_LBTIPORIGA 175 #define NPIEDI 40 typedef real array_piede[ NPIEDI ]; // Definizione della classe dell'applicazione motore class TMotore_application : public TRelation_application { // Array di totalizzatori array_piede _piedi; array_piede _piedi_temp; // Record array per la gestione delle righe TRecord_array* _righe_rec; // Puntatore al profilo del documento caricato TConfig* _pro; // Puntatore al nome, per evitare di ricrearlo se è uguale TFilename* _proname; // Puntatore alla maschera di ricerca TMask* _msk; // Puntatore alla maschera di modifica/inserimento ( dipende dal profilo ) TMask_vendite* _msk1; // puntatore alla relazione TRelation* _rel; // Puntatore allo sheet delle righe documento TSheet_field* _sheet; // Oggetto cliente per il motore TCliForVendite* _clifor; // Indica se il documento ha come soggetto un liente o un ornitore char _tipocf; // Ridefinizione dei metodi virtuali virtual bool user_create( ); virtual bool user_destroy( ); virtual TMask* get_mask(int mode); virtual bool changing_mask(int mode); virtual TRelation* get_relation( ) const { return _rel;} virtual void init_insert_mode( TMask& m ); virtual int read( TMask& m ); virtual bool remove( void ); virtual int write(const TMask& m); virtual int rewrite(const TMask& m); // Punti di ingresso per le funzioni utente // Funzioni da associare ad ogni procedura int user_function( int index ); // Funzioni per il calcolo delle righe real user_row_calculate( TRectype& row, int index ); void user_set_handler( int fieldid, int index, TMask* m = NULL ); long prossimo_numero( bool provv ); int avanza_numero( bool provv ); void get_edit_mask( void ); void azzera_piedi( bool temp = FALSE ); void carica_piedi( ); void somma_piedi( ); void sottrai_piedi( ); // Esegue, se c'è, la procedura utente relativa ad una certa operazione int esegui_procedura( int operazione ); protected: // Procedure e funzioni per la gestione della maschera e dei files void read_rdoc(TMask& m); // formato dipendente dallo sheet (sono le varie colonne) void load_riga( TSheet_field& f, int numrig, TRectype& r ); void store_riga( TSheet_field& f, int numrig, TRectype& r ); void save(TRelation* r) const; void set_descr (int numrig, const char* descr); void carica_righe_libere(int from = -1); bool check_key( TLocalisamfile& rdoc, TString16 codnum, bool provv, TString16 _anno, TString16 _ndoc ); // Procedure e funzioni per la gestione degli stati void setta_stato_corrente( int nuovostato ); const char* nome_sezione( int op ); int stato_corrente( ); int stato_finale( int operazione ); bool stato_valido( int stato, int operazione ); void segnala_stato_non_valido( int operazione ); TString& stati_validi( int operazione ){ return ( pro( ).get( "STATIVALIDI", nome_sezione( operazione ) ) );}; void calcola_riga( TRectype& rdoc, bool temp = FALSE ); // Handle che ritorna la maschera per le righe static TMask * ss_getmask( int numriga, TMask& fullmask, bool destroy ); // Handler che gestisce la richiesta del tipo riga in inserimento static bool ss_handler( TSheet_field& ss, int r, KEY key ); // Handler per la maschera di ricerca static bool ndoc_handler(TMask_field& f, KEY key); static bool num_handler(TMask_field& f, KEY key); static bool tip_handler(TMask_field& f, KEY key); // Handler per la maschera di modifica static bool clifo_handler(TMask_field& f, KEY key); static bool occas_handler(TMask_field& f, KEY key); // Configurazione dello sheet dato il profilo void configura_sheet( TSheet_field& sheet, TConfig& config ); public: // Funzioni di accesso alle variabili privste TRecord_array& righe_rec( ) { CHECK( _righe_rec, "Record array delle righe nullo!" ); return * _righe_rec; }; TConfig& pro( ) { CHECK( _pro, "Profilo del documento nullo!" ); return *_pro; }; TFilename& proname( ) { CHECK( _proname, "Nome del profilo nullo!" ); return *_proname; }; TMask& query_mask( ) { CHECK( _msk, "Maschera di ricerca nulla!" ); return *_msk; }; TMask& edit_mask( ) { CHECK( _msk1, "Maschera di modifica nulla!" ); return *_msk1; }; TRelation& rel( ) { CHECK( _rel, "Relazione nulla!" ); return *_rel; }; TSheet_field& sheet( ) { CHECK( _sheet, "Sheet nullo!" ); return *_sheet; }; TCliForVendite& clifo( ) { CHECK( _clifor, "Oggetto cliente nullo!" ); return *_clifor; }; // Operazione const char tipocf( ){ return _tipocf; } void tipocf( const char tcf ){ _tipocf = tcf; } bool valida_operazione( int operazione ); TSheet_field& ss( ) const { return *_sheet; } TMotore_application( ) { _pro = NULL; } virtual ~TMotore_application( ) { if ( _pro ) delete _pro; } virtual const char* get_next_key( ); }; HIDDEN TMotore_application& app( ) { return (TMotore_application&) main_app( ); } void TMotore_application::init_insert_mode( TMask& m ) { m.set( F_DATAINSC, m.get( F_DATADOC ) ); m.reset( ); clifo( ).occas_mask( ).reset( ); }; int TMotore_application::user_function( int index ) { switch( index ) { case 1: break; default: yesnofatal_box( "Chiamata ad una procedura utente non definita: %d", index ); return NOERR; break; }; return NOERR; }; // Funzione che dato il profilo di riga ottiene la maschera // Serve per ottenere una maschera diversa per ogni riga // Da migliorare, mettendo una cache TMask *TMotore_application::ss_getmask( int numriga, TMask& fullmask, bool destroy ) { static TMask* m; if ( destroy ) { delete m; return( NULL ); } else { TFilename nome_proriga( fullmask.get( 103 ) ); nome_proriga.ext( "ini" ); TConfig proriga( nome_proriga ); m = new TMask( proriga.get( "MSK", "MAIN" ) ); int numhandler = proriga.get_int( "NHANDLER", "HANDLERS" ); for( int i = 1; i <= numhandler; i ++ ) { TString chiave; chiave.format( "%d", i ); TToken_string riga = proriga.get( chiave, "HANDLERS" ); app().user_set_handler( riga.get_int( 0 ), riga.get_int( 1 ), m ); }; return( m ); } } real TMotore_application::user_row_calculate( TRectype& r, int index ) { switch( index ) { case 100: return( f100( r ) ); break; case 200: return( f200( r ) ); break; case 300: return( f300( r ) ); break; case 400: return( f400( r ) ); break; case 500: return( f500( r ) ); break; case 600: return( f600( r ) ); break; default: CHECK( FALSE, "Tentativo di chiamare una funzione di calcolo riga inesistente!" ); return 0.0; } }; void TMotore_application::user_set_handler( int fieldid, int index, TMask* m ) { if( !m ) m = &edit_mask( ); switch( index ) { case 1: m->set_handler( fieldid, ora_hndl ); break; case 2: m->set_handler( fieldid, codcli_hndl ); break; case 3: m->set_handler( fieldid, dummy_hndl ); break; default: CHECK( FALSE, "Tentativo di installare un handler non definito" ); break; } }; bool TMotore_application::ss_handler( TSheet_field& ss, int r, KEY key ) { if ( key == K_SPACE ) // Inizio modifica { app().azzera_piedi( TRUE ); TRelation rdoc( LF_RIGHEDOC ); ss.sheet_mask( ).autosave( &rdoc ); // Mi calcolo nei piedi temporanei la riga app().calcola_riga( rdoc.curr( ), TRUE ); } if ( key == K_TAB ) // Mi posiziono su di una riga nello sheet { TRelation rdoc( LF_RIGHEDOC ); TToken_string riga( ss.row( r ) ); rdoc.curr( ).zero( ); rdoc.curr( ).put( "CODNUM", app( ).edit_mask( ).get( F_CODNUM ) ); rdoc.curr( ).put( "ANNO", app( ).edit_mask( ).get( F_ANNO ) ); rdoc.curr( ).put( "PROVV", app( ).edit_mask( ).get( F_PROVV ) ); rdoc.curr( ).put( "NDOC", app( ).edit_mask( ).get( F_NDOC ) ); rdoc.curr( ).put( "NRIGA", riga.get( 1 ) ); rdoc.read( ); app( ).edit_mask( ).field( F_MEMORIGA ).autoload( &rdoc ); } if ( key == K_TAB ) // Lascio una riga nello sheet { TRelation rdoc( LF_RIGHEDOC ); TToken_string riga( ss.row( r ) ); rdoc.curr( ).zero( ); rdoc.curr( ).put( "CODNUM", app( ).edit_mask( ).get( F_CODNUM ) ); rdoc.curr( ).put( "ANNO", app( ).edit_mask( ).get( F_ANNO ) ); rdoc.curr( ).put( "PROVV", app( ).edit_mask( ).get( F_PROVV ) ); rdoc.curr( ).put( "NDOC", app( ).edit_mask( ).get( F_NDOC ) ); rdoc.curr( ).put( "NRIGA", riga.get( 1 ) ); rdoc.read( ); app( ).edit_mask( ).field( F_MEMORIGA ).autosave( &rdoc ); rdoc.write( ); } if ( key == K_INS ) // Inserimento { TMask& m = *app( )._msk1; TTable tabtr( "%TRI" ); tabtr.zero( ); tabtr.put( "CODTAB", m.get( F_LBTIPORIGA ) ); tabtr.read( ); TToken_string& riga = ss.row( r ); riga.add( 1, 0 ); riga.add( m.get( F_LBTIPORIGA ), 1 ); riga.add( tabtr.get( "S4" ), 2 ); return TRUE; } if ( key == K_CTRL + K_INS ) // Dopo inserimento { TMask& m = *app( )._msk1; TTable tabtr( "%TRI" ); tabtr.zero( ); tabtr.put( "CODTAB", m.get( F_LBTIPORIGA ) ); tabtr.read( ); TToken_string& riga = ss.row( r ); TFilename nome_proriga( tabtr.get( "S4" ) ); nome_proriga.ext( "ini" ); TConfig pro( nome_proriga ); int ncols = pro.get_int( "NCOLS", "COLUMNS" ); // Disabilita tutte le colonne for( int i = 1; i <= MAX_COLUMNS; i ++ ) ss.disable_cell ( ss.items( ) - 1, i ); // Abilita le colonne indicate nel profilo della riga for( i = 1; i <= ncols; i ++ ) { TString16 chiave; chiave.format( "%d", i ); int coltoenable = pro.get_int( chiave, "COLUMNS" ); ss.enable_cell ( ss.items( ) - 1, coltoenable - 1 ); }; ss.force_update( ); app( ).curr_mask( ).send_key( K_ROWEDIT, F_SHEET ); return TRUE; } if ( key == K_DEL ) // Cancellazione { // Sottraggo la riga appena cancellata ai totalizzatori app().sottrai_piedi( ); app().carica_piedi( ); } if ( key == K_ENTER ) // Modifica { app().sottrai_piedi( ); TRelation rdoc( LF_RIGHEDOC ); ss.sheet_mask( ).autosave( &rdoc ); // Sommo la riga ai totalizzatori app().calcola_riga( rdoc.curr( ) ); app().sottrai_piedi( ); } return TRUE; }; bool TMotore_application::num_handler( TMask_field& f, KEY key ) { // Ottengo la maschera TMask& m = f.mask( ); if (key == K_TAB && m.is_running( ) ) { // Se la numerazione non è specificata, const TString16 value( m.get( F_CODNUM ) ); if ( value.blank( ) ) { // Pulisce la descrizione m.set(F_DESNUM, "" ); // Pulisce i tipi di documento consentiti m.set(F_TIPIDOCS, "" ); // Pulisce il tipo di documento m.set(F_TIPODOC, "" ); return TRUE; } // Apro la tabella numerazioni TTable tabnum( "NUM" ); tabnum.zero( ); tabnum.put( "CODTAB", value ); if( tabnum.read( ) == NOERR ) { // Copio la descrizione della numerazione m.set(F_DESNUM, tabnum.get("S0") ); // Copio i tipi di documento validi per la numerazione const TString tipidocs( tabnum.get("S2") ); m.set(F_TIPIDOCS, tipidocs ); TString16 curtipo( m.get( F_TIPODOC ) ); if( curtipo.blank( ) ) { // Propone il primo tipo di documento come default m.set(F_TIPODOC, tipidocs.left( 4 ) ); // m.field( F_TIPODOC ).check( ); m.send_key( K_TAB, F_TIPODOC ); } // Se per questa numerazione è abilitata le numerazione provvisoria if ( tabnum.get_bool ( "B0" ) ) { // Setta di default la numerazione provvisoria m.set( F_PROVV, "P" ); // Abilita il campo per la selezione della numerazione m.enable( F_PROVV ); } else // Altrimenti ... { // Setta la numerazione a definitiva m.set( F_PROVV, "D" ); // Disabilita il campo per la selezione della numerazione m.disable( F_PROVV ); }; return TRUE; } message_box( "Numerazione non valida!" ); return FALSE; } if (key == K_ENTER && m.is_running( ) ) { // Se la numerazione non è specificata, const TString16 value( m.get( F_CODNUM ) ); if ( value.blank( ) ) { message_box( "Occorre una numerazione per inserire un documento!" ); m.first_focus( F_NDOC ); return FALSE; } } return TRUE; } bool TMotore_application::occas_handler(TMask_field& f, KEY key) { if (key == K_SPACE && f.mask( ).is_running( ) ) { TMask& om = app( ).clifo( ). occas_mask( ); om.run( ); f.set_focus( ); } return TRUE; } bool TMotore_application::tip_handler(TMask_field& f, KEY key) { TMask& m = f.mask( ); if (key == K_TAB && m.is_running( ) ) { const TString16 value( m.get( F_TIPODOC ) ); if ( value.blank( ) ) { // Pulisce il profilo m.set(F_PROFILO, "" ); return TRUE; } TString tipi_consentiti( m.get( F_TIPIDOCS ) ); TString16 tipo( f.get( ) ); tipo.trim( ); bool tipo_valido = FALSE; for ( int i = 0; i < 10; i ++ ) { TString16 curtipo( tipi_consentiti.mid( i * 4, 4 ) ); curtipo.trim( ); if( curtipo == tipo ) { tipo_valido = TRUE; break; } } if( ! tipo_valido ) { message_box( "Tipo non valido per la numerazione selezionata!" ); f.set( "" ); return FALSE; } TTable tabtip( "%TIP" ); tabtip.zero( ); tabtip.put( "CODTAB", tipo ); tabtip.read( ); m.set(F_DESTIPODOC, tabtip.get("S0") ); m.set(F_PROFILO, tabtip.get("S4") ); } if (key == K_ENTER && m.is_running( ) ) { TString tipo( f.get( ) ); if ( ! tipo.blank( ) ) { TTable tabtip( "%TIP" ); tabtip.read( ); m.set(F_PROFILO, tabtip.get("S4") ); } else { message_box( "Occorre un tipo documento per inserire un documento!" ); m.first_focus( F_TIPODOC ); return FALSE; } } return TRUE; } bool TMotore_application::ndoc_handler(TMask_field& f, KEY key) { TMask& m = f.mask( ); if (key == K_TAB && m.is_running( ) ) { TLocalisamfile& doc = app( ).rel( ).lfile( ); doc.zero( ); doc.put("CODNUM", m.get( F_CODNUM ) ); doc.put("PROVV", m.get( F_PROVV ) ); doc.put("ANNO", m.get( F_ANNO ) ); doc.put("NDOC", f.get( ) ); if ( doc.read( ) == NOERR ) { m.set(F_TIPODOC, doc.get( "TIPODOC" ) ); m.set(F_STATO, doc.get( "STATO" ) ); TTable tabtip( "%TIP" ); tabtip.put( "CODTAB", doc.get( "TIPODOC" ) ); tabtip.read( ); m.set(F_PROFILO, tabtip.get("S4") ); m.stop_run( K_AUTO_ENTER ); } } return TRUE; } bool TMotore_application::clifo_handler(TMask_field& f, KEY key) { if (key == K_TAB && f.active()) { TMask& m = f.mask(); const char cf = app().tipocf(); TLocalisamfile& clifo = ((TEdit_field&)f).browse()->cursor()->file(); if (clifo.get_char("TIPOCF") != cf || clifo.get("CODCF") != f.get()) { clifo.setkey(1); clifo.put("TIPOCF", cf); clifo.put("CODCF", f.get()); clifo.read(); CHECK(clifo.good(), "Impossibile ritrovare il clifo" ); } CHECKD(f.is_edit(), "Can't check suspension of a non edit-field ", f.dlg()); const TEdit_field& c = (const TEdit_field&)f; const TBrowse* b = c.browse(); CHECKD(b, "Can't check suspension of a edit-field without a USE ", f.dlg()); const TLocalisamfile& i = b->cursor()->file(); // Tabella File const char* sf = i.tab() ? "B2" : "SOSPESO"; const bool suspended = i.get_bool(sf); if (suspended) { sf = f.get(); return f.error_box("Il codice '%s' e' sospeso e non puo' essere utilizzato", sf); } /* if (!m.is_running() || f.dirty()) { // Equichecazzociva? } */ // Disabilitazioni varie, ma le demando all'oggetto cliente if (f.focusdirty()) { app().clifo( ).load( cf, atol( f.get( ) ), "" ); app().clifo( ).update_mask( ( TMask_vendite& ) m ); if ( app( ).clifo( ).occasionale( ) && app( ).clifo( ).occas_mask( ).get(O_CODICE).empty( ) ) m.send_key(K_SPACE, F_OCCASEDIT); // Lancia maschera occasionali } } return TRUE; } void TMotore_application::azzera_piedi( bool temp ) { for ( int i = 0; i < NPIEDI; i++ ) if ( temp ) _piedi_temp[ i ] = 0.0; else _piedi[ i ] = 0.0; } void TMotore_application::carica_piedi( ) { TToken_string s( pro( ).get( "PROGPIEDE", "MAIN" ) ); int i = s.get_int( ); int j = 0; while( i != 0 ) { real strpiede( _piedi[ i ] ); edit_mask( ).set( BASE_PIEDE + ( ++j ), strpiede.stringa( 15 ) ); i = s.get_int( ); } } void TMotore_application::somma_piedi( ) { for ( int i = 0; i < NPIEDI; i++ ) _piedi[ i ] += _piedi_temp[ i ]; } void TMotore_application::sottrai_piedi( ) { for ( int i = 0; i < NPIEDI; i++ ) _piedi[ i ] -= _piedi_temp[ i ]; } bool TMotore_application::changing_mask(int mode) { static int lastmode = NO_MODE; const bool change = ( mode != lastmode ); lastmode = mode; return change; } void TMotore_application::configura_sheet( TSheet_field& sheet, TConfig& config ) { int ncols = config.get_int( "NCOLS", "SHEET" ); for( int i = 1; i <= ncols; i ++ ) { TString col; col.format( "%d", i ); TToken_string sheet_col( config.get( col, "SHEET" ) ); const TString descr( sheet_col.get( 1 ) ); if ( ! descr.blank( ) ) sheet.set_column_header( i, descr ); TString size( sheet_col.get( 2 ) ); if ( ! size.blank( ) ) sheet.set_column_width( i, sheet_col.get_int( 2 ) ); int coltomove = sheet_col.get_int( 0 ) - 1; sheet.move_column( coltomove, i ); }; for ( int j = MAX_COLUMNS; j >= i - 1; j -- ) sheet.delete_column( j ); }; void TMotore_application::get_edit_mask( void ) { TFilename fn; fn = query_mask( ).get( F_PROFILO ); // query_mask( ).enable(DLG_NEWREC); fn.ext( "ini" ); fn.upper( ); if ( _pro ) { if( (*_proname) == fn ) return; delete _pro; }; _pro = new TConfig( fn ); _proname = new TFilename( fn ); _proname->upper( ); if ( _msk1 ) delete _msk1; _msk1 = new TMask_vendite( pro( ).get( "MSKFILE", "MAIN" ) ); // edit_mask( ).set( F_PROFILO, query_mask( ).get( F_PROFILO ) ); edit_mask( ).set( F_DESNUM, query_mask( ).get( F_DESNUM ) ); _sheet = &(TSheet_field &)edit_mask( ).field(F_SHEET); sheet( ).set_notify( ss_handler ); TString tipocf( app( ).pro( ).get( "TIPOCF", "MAIN" ) ); app( ).tipocf( tipocf[ 0 ] ); configura_sheet( *_sheet, *_pro ); TList_field& listbox = ( TList_field& ) _msk1->field( F_LBTIPORIGA ); const int numtr = app( ).pro( ).get_int( "NTIPIRIGA", "RIGHE" ); TTable tabtr( "%TRI" ); TToken_string keys( "" ), descrs( "" ); for ( int i = 1; i <= numtr; i ++ ) { TString chiave; TToken_string item; chiave.format( "%d", i ); tabtr.zero( ); TString tiporiga( app( ).pro( ).get( chiave, "RIGHE" ) ); tabtr.put( "CODTAB", tiporiga ); if ( tabtr.read( ) == NOERR ) { keys.add( tabtr.get( "CODTAB" ) ); descrs.add( tabtr.get( "S0" ) ); } else { yesnofatal_box( "Inserito un tipo di riga non valido (%s)", (const char *)tiporiga ); } } listbox.replace_items( keys, descrs ); sheet( ).set_getmask( ss_getmask ); int numhandler = pro( ).get_int( "NHANDLER", "HANDLERS" ); for( i = 1; i <= numhandler; i ++ ) { TString chiave; chiave.format( "%d", i ); TToken_string riga = pro( ).get( chiave, "HANDLERS" ); user_set_handler( riga.get_int( 0 ), riga.get_int( 1 ) ); }; _msk1->set( F_MEMORIGA, "Riga1" ); } TMask* TMotore_application::get_mask( int mode ) { switch ( mode ) { case MODE_INS: case MODE_MOD: get_edit_mask( ); edit_mask( ).enable( DLG_PRINT, ( mode == MODE_MOD ) ); edit_mask( ).set_handler( F_OCCASEDIT, occas_handler ); edit_mask( ).set_handler( F_CODCF, clifo_handler ); edit_mask( ).set_handler( F_CODPAG, condpag_hndl ); edit_mask( ).set_handler( F_DATAINSC, condpag_hndl ); return ( _msk1 ); break; default: return _msk; break; }; } void TMotore_application::set_descr(int i, const char * dfi) { TToken_string& r = ss( ).row(i); r.add(dfi, 0); } void TMotore_application::carica_righe_libere(int from) { if (from < 0) from = ss( ).items( ); for (int i = from; i < 20; i++) set_descr( i, "" ); ss( ).force_update( ); } const char* TMotore_application::get_next_key( ) { TToken_string key; TMask& m = curr_mask( ); TString value = m.get( F_CODNUM ); if ( value.blank( ) ) return NULL; TTable tabnum( "NUM" ); tabnum.zero( ); tabnum.put( "CODTAB", value ); if( tabnum.read( ) == NOERR ) { // Se per questa numerazione è abilitata le numerazione automatica if( tabnum.get_bool ( "B1" ) ) { TLocalisamfile doc( LF_DOC ); doc.zero( ); doc.put( "CODNUM", value ); doc.put( "ANNO", m.get( F_ANNO ) ); doc.put( "NDOC", 9999999L ); // Se per questa numerazione è abilitata le numerazione provvisoria if( tabnum.get_bool ( "B0" ) ) { doc.put( "PROVV", "P" ); } else // Altrimenti ... { doc.put( "PROVV", "D" ); }; if( doc.read( _isgteq ) == NOERR ) { doc.prev( ); } long num = ( value == doc.get( "CODNUM" ) ) ? doc.get_long( "NDOC" ) : 0; key.format( "%d|%d", F_NDOC, num + 1 ); return key; } }; return NULL; } int TMotore_application::read(TMask& m) { azzera_piedi( ); int err = TRelation_application::read( m ); if ( err == NOERR ) { TString16 tipocf( m.get( F_TIPOCF ) ); clifo( ).load( tipocf[ 0 ], m.get_int( F_CODCF ), rel( ).curr( ).get( "OCFPI" ) ); clifo( ).update_mask( ( TMask_vendite& ) m, TRUE ); TLocalisamfile& rdoc = rel( ).lfile(LF_RIGHEDOC); TRectype r = rdoc.curr( ); r.zero( ); r.put( "CODNUM", m.get( F_CODNUM ) ); r.put( "PROVV", m.get( F_PROVV ) ); r.put( "ANNO", m.get( F_ANNO ) ); r.put( "NDOC", m.get_long( F_NDOC ) ); _righe_rec->read( r ); TSheet_field& f = (TSheet_field&) m.field( F_SHEET ); f.destroy( ); int last = _righe_rec->last_row( ); for( int i = 1; i <= last; i ++ ) { TRectype &rec = _righe_rec->row( i, TRUE ); load_riga( f, i - 1, rec ); calcola_riga( rec ); }; carica_piedi( ); } return err; } bool TMotore_application::check_key( TLocalisamfile& rdoc, TString16 codnum, bool provv, TString16 anno, TString16 ndoc ) { return ( ( rdoc.get("CODNUM") == codnum ) && ( rdoc.get("NDOC") == ndoc ) && ( rdoc.get("ANNO" ) == anno ) && ( rdoc.get_bool( "PROVV" ) == provv ) ); } int TMotore_application::write(const TMask& m) { int err; if ( esegui_procedura( OP_NUOVO ) != NOERR ) return FALSE; err = NOERR; // avanza_numero( m.get_bool( F_PROVV ) ); if ( err == NOERR ) { err = app( ).clifo( ).write_occas( ); } if ( err == NOERR ) { err = TRelation_application::write( m ); if ( err == NOERR ) { TSheet_field& f = ss( ); _righe_rec->destroy_rows( ); if ( m.insert_mode( ) ) _righe_rec->renum_key( "NRIGA", 1 ); for ( int i = 0; i < f.items( ); i ++ ) { TToken_string& t = f.row( i ); TRectype& rec = _righe_rec->row(i + 1, TRUE); store_riga( f, i, rec ); } err = _righe_rec->write( ); } } return err; }; int TMotore_application::rewrite(const TMask& m) { if ( ! valida_operazione( OP_MODIFICA ) ) return FALSE; int err = TRelation_application::rewrite( m ); if ( err == NOERR ) { TSheet_field& f = ss( ); _righe_rec->destroy_rows( ); if ( m.insert_mode( ) ) _righe_rec->renum_key( "NRIGA", 1 ); for ( int i = 0; i < f.items( ); i ++ ) { TToken_string& t = f.row( i ); TRectype& rec = _righe_rec->row(i + 1, TRUE); store_riga( f, i, rec ); } err = _righe_rec->rewrite( ); } return err; }; // La funzione si trova in ve0100b long TMotore_application::prossimo_numero( bool provv ) { long ret; TTable tabnum( "NUM" ); tabnum.read( ); if ( provv ) ret = tabnum.get_long( "I0" ) + 1; else ret = tabnum.get_long( "I1" ) + 1; return ( ret ); }; int TMotore_application::avanza_numero( bool provv ) { TTable tabnum( "NUM" ); int err = tabnum.read( ); if ( err == NOERR ) { if ( provv ) tabnum.put( "I0", tabnum.get_long( "I0" ) + 1 ); else tabnum.put( "I1", tabnum.get_long( "I1" ) + 1 ); err = tabnum.rewrite( ); } return err; }; bool TMotore_application::remove( void ) { if ( ! valida_operazione( OP_CANCELLA ) ) return FALSE; return TRelation_application::remove && ( _righe_rec->remove( ) == NOERR ); } void TMotore_application::load_riga( TSheet_field& f, int numrig, TRectype& r ) { TToken_string& riga = f.row(numrig); riga = r.get( "STATORIGA" ); riga.add( r.get( "TIPORIGA" ) ); TFilename proname( r.get( "PROFRIGA" ) ); riga.add( proname ); riga.add( r.get( "CODMAG" ) ); riga.add( r.get( "CODART" ) ); riga.add( r.get( "DESCR" ) ); riga.add( r.get( "DESCLUNGA" ) ); riga.add( r.get( "PREZZO" ) ); riga.add( r.get( "UMQTA" ) ); riga.add( r.get_real( "QTA" ).string(11) ); riga.add( r.get( "QTAEVASA" ) ); riga.add( r.get( "RIGAEVASA" ) ); riga.add( r.get( "TARA" ) ); riga.add( r.get( "PNETTO" ) ); riga.add( r.get( "NCOLLI" ) ); riga.add( r.get( "DAEVADERE" ) ); riga.add( r.get( "SCONTO" ) ); riga.add( r.get( "PERCPROV" ) ); riga.add( r.get( "IMPFISSO" ) ); riga.add( r.get( "IMPFISUN" ) ); riga.add( r.get( "CODIVA" ) ); riga.add( r.get( "ADDIVA" ) ); riga.add( r.get( "ASPBENI" ) ); proname.ext( "ini" ); TConfig pro( proname ); int ncols = pro.get_int( "NCOLS", "COLUMNS" ); // Disabilita tutte le colonne for( int i = 1; i <= MAX_COLUMNS; i ++ ) f.disable_cell ( f.items( ) - 1, i ); // Abilita le colonne indicate nel profilo della riga for( i = 1; i <= ncols; i ++ ) { TString16 chiave; chiave.format( "%d", i ); int coltoenable = pro.get_int( chiave, "COLUMNS" ); f.enable_cell ( numrig - 1, coltoenable - 1 ); } } void TMotore_application::store_riga( TSheet_field& f, int numrig, TRectype& r ) { TToken_string& riga = f.row(numrig); r.put( "CODNUM", edit_mask( ).get( F_CODNUM ) ); r.put( "ANNO", edit_mask( ).get( F_ANNO ) ); r.put( "PROVV", edit_mask( ).get( F_PROVV ) ); r.put( "NDOC", edit_mask( ).get_long( F_NDOC ) ); r.put( "STATORIGA", riga.get( 0 ) ); r.put( "TIPORIGA", riga.get( 1 ) ); r.put( "PROFRIGA", riga.get( 2 ) ); r.put( "CODMAG", riga.get( 3 ) ); r.put( "CODART", riga.get( 4 ) ); r.put( "DESCR", riga.get( 5 ) ); r.put( "DESCLUNGA", riga.get( 6 ) ); r.put( "PREZZO", riga.get( 7 ) ); r.put( "UMQTA", riga.get( 8 ) ); r.put( "QTA", riga.get( 9 ) ); r.put( "QTAEVASA", riga.get( 10 ) ); r.put( "RIGAEVASA", riga.get( 11 ) ); r.put( "TARA", riga.get( 12 ) ); } void TMotore_application::calcola_riga( TRectype& r, bool temp ) { TFilename proriganame( r.get("PROFRIGA") ); proriganame.ext( "INI" ); TConfig proriga( proriganame ); TToken_string s(proriga.get("PROGPIEDE", "MAIN")); int func = s.get_int( ); while( func ) { if ( temp ) _piedi_temp[ s.get_int( ) ] += user_row_calculate( r, func ); else _piedi[ s.get_int( ) ] += user_row_calculate( r, func ); func = s.get_int( ); } } bool TMotore_application::user_create( ) { TSconto s; s.set( "12 - 23 + 12.2 +.5 ", TRUE ); if( s.is_valid( ) ) warning_box( "Sconto: %s( %s )", (const char *)s.get( ), (const char *)s.scontostr( ) ); s.set( ".5-.5", TRUE ); if( s.is_valid( ) ) warning_box( "Sconto: %s( %s )", (const char *)s.get( ), (const char *)s.scontostr( ) ); s.set( "12 - 2.3 + 12.2.1 +.5 ", TRUE ); if( s.is_valid( ) ) warning_box( "Sconto: %s( %s )", (const char *)s.get( ), (const char *)s.scontostr( ) ); TConfig ditta( CONFIG_DITTA ); // Controllo se sono cambiate le impostazioni delle vendite. if( ditta.get_bool( "CHANGED", "ve" ) ) { // Se sono cambiate, rigenero tutte le maschere if ( !yesno_box( CHANGE_MESSAGE ) ) return FALSE; TExternal_app motore2( "VE0 -3 -all" ); motore2.run( ); ditta.set( "CHANGED", "", "ve" ); } _clifor = new TCliForVendite( ); azzera_piedi( ); _msk = new TMask("VE1000A"); query_mask( ).set_handler( F_NDOC, ndoc_handler ); query_mask( ).set_handler( F_CODNUM, num_handler ); query_mask( ).set_handler( F_TIPODOC, tip_handler ); TConfig utente( CONFIG_USER ); TString16 codnum( utente.get( "CODNUM", "ve") ); if (!codnum.blank( ) ) { query_mask( ).set( F_CODNUM, codnum ); query_mask( ).set( F_DESNUM, utente.get( "DESNUM", "ve") ); } TString16 tipodoc( utente.get( "TIPODOC", "ve") ); if (!tipodoc.blank( ) ) { query_mask( ).set( F_TIPODOC, tipodoc ); query_mask( ).set( F_DESTIPODOC, utente.get( "DESTIPODOC", "ve") ); } // La maschera di inserimento/modifica per ora non la so! // Viene letta dal profilo non appena trovato il record _msk1 = NULL; // Metto in relazione testata e righe _rel = new TRelation(LF_DOC); rel( ).add( LF_RIGHEDOC,"CODNUM=CODNUM|ANNO=ANNO|PROVV=PROVV|NDOC=NDOC" ); // Inizializzo il Record_array _righe_rec = new TRecord_array( LF_RIGHEDOC, "NRIGA", 1 ); return TRUE; } bool TMotore_application::user_destroy( ) { // Registro l'ultimo tipo documento e l'ultima numerazione TConfig utente( CONFIG_USER ); utente.set( "CODNUM", query_mask( ).get( F_CODNUM ), "ve" ); utente.set( "TIPODOC", query_mask( ).get( F_TIPODOC ), "ve" ); utente.set( "DESNUM", query_mask( ).get( F_DESNUM ), "ve" ); utente.set( "DESTIPODOC", query_mask( ).get( F_DESTIPODOC), "ve" ); // Se è ancora allocata, distruggo la maschera di modifica if ( _msk1 ) delete _msk1; // Distruggo la maschera di modifica delete _msk; // Distruggo la relazione delete _rel; // Distruggo il Record_array delete _righe_rec; return TRUE; } int TMotore_application::esegui_procedura( int operazione ) { // Accesso unico alla chiamata di procedure tramite operazione int index = ( int )pro( ).get_long( nome_sezione( operazione ), "MAIN" ); if ( index ) return ( user_function( index ) ); return ( NOERR ); } bool TMotore_application::valida_operazione( int operazione ) { if ( operazione != OP_NUOVO ) { if ( !stato_valido( stato_corrente( ), operazione ) ) { segnala_stato_non_valido( operazione ); return FALSE; } }; if ( esegui_procedura( operazione ) == NOERR ) return FALSE; return TRUE; } const char * TMotore_application::nome_sezione( int op ) { switch( op ) { case OP_NUOVO: return "INSERIMENTO"; break; case OP_MODIFICA: return "MODIFICA"; break; case OP_CANCELLA: return "CANCELLAZIONE"; break; case OP_STAMPA: return "STAMPA"; break; case OP_RAGGRUPPA: return "RAGGRUPPA"; break; case OP_USER: return "SPECIALE"; break; default: CHECK( FALSE, "tentativo di ottenere il nome di una operazione inesistente!" ); // Per evitare la warning return ""; break; } } int TMotore_application::stato_finale( int operazione ) { TString s( pro( ).get( "STATOFINALE", nome_sezione( operazione ) ) ); if( strcmp( s, "N" ) == 0 ) return NO_CHANGE_STATUS; return ( atoi( s ) ); }; bool TMotore_application::stato_valido( int stato, int operazione ) { #ifdef _DEBUG warning_box( "Controllo stati validi!\nStato corrente %d.\nStati validi %s.", stato_corrente( ), ( const char * )stati_validi( operazione ) ); #endif char p[2] = "0"; TToken_string ret ( stati_validi( operazione ), ',' ); p[0] += (char)stato; return ( ret.get_pos( p ) != -1 ); }; void TMotore_application::setta_stato_corrente( int nuovostato ) { // warning_box( "Settaggio stati validi!\nStato corrente %s.\nStati validi %s.\nStato finale %s.", stato_corrente( ), stati_validi( operazione ), stato_finale( operazione ) ); TString p; p.format( "%d", nuovostato ); TLocalisamfile& doc = rel( ).lfile(LF_DOC); p[0] += (char)nuovostato; doc.put("STATO", p); doc.rewrite( ); query_mask( ).set( F_STATO, p ); // warning_box( "Settaggio stati validi!\nStato corrente %s.\nStati validi %s.\nStato finale %s.", stato_corrente( ), stati_validi( operazione ), stato_finale( operazione ) ); } int TMotore_application::stato_corrente( ) { int i = query_mask( ).get_int( F_STATO ); return ( i == 0 ? NO_DOC_STATUS : i ); }; void TMotore_application::segnala_stato_non_valido( int operazione ) { TString messaggio; switch( operazione ) { case OP_NUOVO: // Sempre valido break; case OP_MODIFICA: messaggio = "Il documento non si trova in uno stato valido per poter essere modificato!"; break; case OP_CANCELLA: messaggio = "Il documento non si trova in uno stato valido per poter essere cancellato!"; break; case OP_STAMPA: messaggio = "Il documento non si trova in uno stato valido per poter essere stampato!"; break; case OP_RAGGRUPPA: messaggio = "Il documento non si trova in uno stato valido per poter essere raggruppato!"; break; case OP_USER: messaggio = "Il documento non si trova in uno stato valido per effettuare la operazione richiesta!"; break; default: CHECK( FALSE, "Tentativo di segnalare stato non valido di una operazione non esistente!" ); break; }; messaggio << "\nStato corrente :%d.\nStati validi :%s."; warning_box( messaggio, stato_corrente( ), ( const char * )stati_validi( operazione ) ); }; int ve0100(int argc, char** argv) { TMotore_application a; a.run(argc, argv, "Gestione documenti"); return 0; }