Motodo th_applymethod

Introduzione

Il metodo th_applymethod che fa parte dei metodi avanzati, consente di poter intervenire sui dati inviati dal server, prima che sia popolata la griglia, quindi consente di intervenire e di operate delle «elaborazioni» su ogni singola riga inviata dal server, consente inoltre di definire e gestire colonne calcolate.

Per il suo funzionamento, ha bisogno di un decoratore che andrà importato in testa al file tramite questa istruzione:

from gnr.core.gnrdecorator import public_method

Inoltre negli esempi verrà utilizzato anche un altro metodo che ha bisogno di un altro decoratore, che definiamo:

from gnr.core.gnrnumber import decimalRound

Anche per questa sezione gli esempi riguardano Sandbox ed in particolare la tabella fattura quindi il file cliente corrispondente sarà th_cliente; dovremmo intervenire su due metodi della risorsa ed in particolare nella th_struct (come vedremo) e nel nuovo metodo che andiamo a descrivere nella sua definizione e funzionamento.

Iniziamo quindi col definire un nuovo metodo:

def th_applymethod(self,selection=None):

Modifica della th_struct

Nella th_struct della risorsa, definiamo una nuova colonna calcolata che verrà utilizzata in seguito:

r.cell('perc_fatturato',
      calculated=True,
      width='7em',
      name='Perc.fatt',
      dtype='N',
      format='###.00',
      totalize=True)

la colonna indica la percentuale del fatturato di ciascun cliente, rispetto al fatturato totale.

Riprendiamo quindi il nuovo metodo di cui poi andremo ad analizzarne il funzionamento:

#1.
@public_method
#2.
def th_applymethod(self,selection=None):
     #3.
     totale_finale = selection.sum('tot_fatturato')[0]
     #4.
     def cb(row):
     #5.
         return dict(perc_fatturato=decimalRound(row['tot_fatturato']/totale_finale*100))
     #6.
     selection.apply(cb)

#1. Aggiungiamo il decoratore

#2. Definizamo la funzione th_applymethod che riceve come parametro la selezione (l’insieme delle righe frutto del risultato della query)

#3. La somma (selection.sum(“tot_f atturato”))ritorna una lista, quindi la selection.sum calcola il totale della colonna “tot_fatturato” e dato che si tratta di una lista si drovrà prendere il primo elemento [0]

#4. Viene definita all’interno del metodo una callback cb(row) che ritorna un dizionario nel quale possiamo far ritornare dei valori calcolati.

#5. In questo caso il dizionario ritorna un valore con chiave “perc_fatturato” e valore calcolato come totale fatturato della riga (row[“tot_fatturato”]) diviso per il totale della selezione corrente (totale_finale). Da osservare che il totale_finale, non è il totale del fatturato di tutti i clienti, ma il totale relativo ai clienti estratti dalla query ovvero dei dati presenti nella view.

#6. la selection.apply(cb) applica la funzione di callback a ciascuna riga, quindi in questo momento per ciscuna riga della grid viene eseguita la funzione e calcolato il valore della colonna perc_fatturato.

Abbiamo visto che in questo caso, la percentuale fatturato per ciascuna riga viene calcolato in base al totale fatturato della selezione.

E se avessimo comunque la necessità di conoscere la percentuale del fatturato di ciascun cliente, non rispetto al totale della selezione ma rispetto al fatturato complessivo indipendente dalla selezione corrente, come potremmo arrivare a questo risultato?

Iniziamo aggiungendo una nuova colonna calcolata perc_glob nella th_struct…

r.cell('perc_glob',
      calculated=True,
      width='7em',
      name='Perc.glob',
      dtype='N',
      format='###.00',
      totalize=True)

e modifichiamo la funzione th_applymethod…

@public_method
def th_applymethod(self,selection=None):
    totale_finale = selection.sum('tot_fatturato')[0]

    #7.
    righe = self.db.table('fatt.fattura'
                    ).query(columns='SUM($totale_fattura) AS tot').fetch()
    #8.
    totale_complessivo = righe[0]['tot']

    def cb(row):
        #9.
        return dict(perc_fatturato=decimalRound(row['tot_fatturato']/totale_finale*100),
                    perc_glob=decimalRound(row['tot_fatturato']/totale_complessivo*100))
    selection.apply(cb)

#7. Viene calcolato, con una query, il totale generale del fatturato, quindi una query senza alcun parametro o condizione.

#8. Dal risultato (righe)si prende dalla «zeresima» riga, il valore con chiave “tot” (impostato nella query da… AS tot)

#9. Nel dizionario che ritorne i valori calcolati per ciascuna riga, viene aggiunta, rispetto alla versione precedente, un nuovo valore dato dal tot_fatturato (totale della selezione) diviso il totale_complessivo (totale generale fatturato)

Attachments: