.. _orm_genropy/virtual_columns/formulaColumn: formulaColumn ============= .. toctree:: :maxdepth: 1 :hidden: :titlesonly: formulaColumn_dinamiche formulacolumn_parametriche La formulaColumn è una colonna virtuale calcolata. È possibile eseguire qualsiasi tipo di operazione con valori proveniente da altre tabelle, anche in relazione. Le operazioni possibili sono tutte quelle consentite da PostgresSQL disponibili nella `Documentazione Ufficiale `_. Questa elaborazione avviene a **ogni caricamento di pagina**, di conseguenza i valori saranno sempre aggiornati in tempo reale. Di seguito alcuni esempi di funzionamento di una formulaColumn. Formule di calcolo di PostgreSQL ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :: tbl.formulaColumn('nome_cognome',"$nome || ' ' || $cognome") :: tbl.formulaColumn('estremi_documento', "$protocollo||' del '||$data") tbl.formulaColumn('indirizzo_completo',"$ragione_sociale||' - '||COALESCE($indirizzo,'')||' - '||COALESCE($cap,'')||' '||COALESCE($localita,'')||' '||COALESCE($provincia,'')") :: tbl.formulaColumn('anno_fattura', "EXTRACT(YEAR FROM $data)") :: tbl.formulaColumn('non_confermato', "$totale IS NULL", dtype='B') tbl.formulaColumn('comunicazione_iva_area',"""CASE WHEN $nazione IS NULL THEN 'IT' WHEN $nazione='SM' THEN 'SM' ELSE 'EX' END""") Uso di select ~~~~~~~~~~~~~ Quando è necessario effettuare delle :ref:`operazioni di lettura` sulle **tabelle** è possibile anche utilizzare l'operatore Genropy *select*, che riceve un dizionario utilizzato per effettuare una *sub-query*. :: tbl.formulaColumn('n_fatture',select=dict(table='fatt.fattura', columns='COUNT(*)', where='$cliente_id=#THIS.id'), dtype='L',name_long='N.Fatture') tbl.formulaColumn('tot_fatturato',select=dict(table='fatt.fattura', columns='SUM($totale_fattura)', where='$cliente_id=#THIS.id'), dtype='N',name_long='Tot.Fatturato') .. hint:: Se il risultato della *select* non è univoco, è possibile utilizzare `limit=1` per prendere solo il primo risultato (eventualmente ordinando i risultati con ``order_by``). Alternativamente, si dovrà concatenare in una stringa i risultati in un'unica stringa. Si noti che è possibile effettuare nella stessa colonna **più operazioni di lettura simultaneamente** con l'uso di select, utilizzando un suffisso a piacere (es: ``select_amount``) e richiamando poi nell'operazione che si desidera (es: *COALESCE*, *SUM*) il suffisso prescelto con `#`:: tbl.formulaColumn('c1_balance_amount_i', 'COALESCE(#amount_i,#first)', select_amount=dict(table='contract.amount', where="""$contratto_id=#THIS.contratto_id AND $data <= #THIS.data_inizio_affido""", columns='$balance_amount', limit=1, order_by='$data DESC'), select_first=dict(table='contract.amount', where="""$contratto_id=#THIS.contratto_id""", columns='$balance_amount', limit=1, order_by='$data ASC'), dtype='money') formulaColumn speciali ~~~~~~~~~~~~~~~~~~~~~~ Esistono alcune formulaColumn particolari che permettono di innescare dei meccanismi automatici sul record. Ad esempio:: tbl.formulaColumn('__protected_by_published',"($published IS TRUE)", dtype='B') bloccherà qualsiasi modifica al record in presenza della condizione specificata (in questo caso l'avvenuta pubblicazione). Oppure:: tbl.formulaColumn('__invalid_by_confirmed',"($confirmed IS FALSE)", dtype='B') segnalerà il record con un semaforo rosso in griglia in presenza della condizione specificata (in questo caso la mancata conferma). .. hint:: Il "nome" della colonna, dopo gli ``_`` ("published" nel primo caso e "confirmed" nel secondo) possono essere modificati a piacere, non è necessario utilizzare il nome della colonna di riferimento per la verifica della condizione. Alternativa alla formulaColumn: ``sql_value`` --------------------------------------------- Come abbiamo detto, la formulaColumn è una colonna virtuale che viene calcolata a ogni caricamento della pagina di Genropy. In alcuni casi in cui questo aggiornamento in tempo reale non è necessario esiste un'alternativa all'uso della formulaColumn, che consiste nell'uso di una :ref:`colonna reale` , dove è possibile indicare una formula di calcolo con il parametro ``sql_value``:: tbl.column('modulo_dflt', sql_value=":area_modulo_dflt||'/'||:codice_modulo_dflt", name_long='Modulo default) In questo modo il valore non sarà calcolato in tempo reale a ogni caricamento, bensì a ogni :ref:`operazione di insert/update` . Oltre a un vantaggio in termini di performance, quindi, la colonna calcolata, essendo una colonna reale, sarà anche disponibile automaticamente in ogni :ref:`lettura del record` , senza necessità di specificare le colonne. .. raw:: html
**Parametri:** +------------------------+------+--------------------------------------------------+ | Nome parametro | Tipo | Descrizione | +========================+======+==================================================+ |value |T |Generalmente implicito, permette di calcolare un | | | |valore secondo una regola definita come una | | | |stringa di SQL | +------------------------+------+--------------------------------------------------+ |static |B | | +------------------------+------+--------------------------------------------------+ |select |T |Alternativamente al value calcolato, la | | | |formulaColumn può restituire un valore originato | | | |da una query, i cui parametri possono essere | | | |indicati con un dizionario all'interno di questo | | | |parametro. Può contenere tutti i parametri di una | | | |query ("table", "where", "columns", "condition", | | | |"order_by", "limit") | +------------------------+------+--------------------------------------------------+ |var\_ |T |È possibile passare tutte le variabili che si | | | |vuole alla formulaColumn precedute da var_ (es: | | | |var_data_rif='2015-01-01'), in questo modo non | | | |andranno a mischiarsi agli altri parametri. | +------------------------+------+--------------------------------------------------+ |ask |T |Permette di identificare in un dizionario i | | | |parametri da richiedere all’utente al | | | |trascinamento della colonna nella vista, che | | | |verranno poi utilizzati dalla colonna (es. ask=dic| | | |t(title='Regione',fields=[dict(name='regione', | | | |tag='dbSelect', table='glbl.regione', | | | |lbl='Regione')])) | +------------------------+------+--------------------------------------------------+ |fieldname |T |In caso di formulaColumn parametriche permette di | | | |pre-impostare un template per la generazione del | | | |nome della colonna, così da non richiederlo | | | |all'utente (es: fieldname='tot_fatt_$data_rif') | +------------------------+------+--------------------------------------------------+ |header |T |In caso di formulaColumn parametriche permette di | | | |pre-impostare un template per la generazione | | | |dell'etichetta della colonna, così da non | | | |richiederla all'utente (es: header='Tot.Fatt. al | | | |$data_rif') | +------------------------+------+--------------------------------------------------+ .. sectionauthor:: Davide Paci