Tabelle di Totalizzazione

Come calcolare i totali con le Totalize Tables

In alcuni casi può essere necessario calcolare i totali di colonna di una table . Si supponga per esempio di avere un magazzino, con dei movimenti di carico e scarico: quello che ci interessa probabilmente è la possibilità di visualizzare in tempo reale il numero di pezzi disponibili di un determinato prodotto, risultante dalla somma dei movimenti di carico e scarico avuta fino a questo momento.

Genropy mette a disposizione uno strumento speciale per questi casi particolari: la Tabella di Totalizzazione, che viene usata per sommare o aggregare campi numerici di, ad esempio, generici archivi di movimenti.

Come definire una Tabella di Totalizzazione

La tabella di totalizzazione ridefinisce la classica Tabella di Genropy al fine di aggiornarsi automaticamente e calcolare in tempo reali i totali tramite un trigger nascosto.

A noi basterà quindi definire una tabella di totalizzazione come segue:

class Table(TotalizeTable):
  def config_db(self,pkg):
      tbl = pkg.table('giacenza_prodotto_deposito', pkey='codekey',
                      pkey_columns='prodotto_id,deposito_id',
                      name_long='!!Giacenze',
                      caption_field='prodotto_id',
                      totalize_maintable='mag_light.movimento_riga')
      self.sysFields(tbl,id=False, ins=False, upd=False, ldel=False,user_ins=False)

      tbl.column('codekey',size=':45',group='zz',name_long='key')
      tbl.column('prodotto_id', size='22', name_long='Prodotto', group='_',
                      totalize_key=True).relation('mag_light.prodotto.id',
                                                        mode='foreignkey',
                                                        relation_name='inventario',
                                                        onDelete='cascade')
      tbl.column('deposito_id', size='22', name_long='Deposito',
                      totalize_key=True).relation('mag_light.deposito.id',
                                                        mode='foreignkey',
                                                        relation_name='inventario',
                                                        onDelete='cascade')
      tbl.column('quantita', dtype='I', name_long = 'Quantità', totalize_value=True)

Innanzitutto specifichiamo tra gli attributi della tabella la totalize_maintable, ovvero la tabella dei movimenti di origine. Sarà poi necessario definire una codekey (che sarà la pkey della tabella di totalizzazione), che sarà costruita come concatenazione dei campi che desideriamo totalizzare (specificati in pkey_columns, in questo caso, i prodotti nei vari depositi). Inoltre, specifichiamo la colonna da totalizzare (quantita), con l’attributo totalize_value=True.

Suggerimento

La totalize_value sarà True se la colonna da totalizzare avrà lo stesso nome della colonna della tabella di origine, altrimenti sarà possibile indicare il nome della colonna da totalizzare (es: totalize_value=”quantita_disponibile”).

Infine, come ultimo passaggio, sarà sufficiente nella tabella di provenienza dei nostri movimenti da totalizzare, andare ad «agganciare» la tabella di totalizzazione specificando totalizer_nomeapiacere='mag_light.giacenza_prodotto_deposito:

class Table(object):
  def config_db(self,pkg):
    tbl=pkg.table('movimento_riga', pkey='id', name_long='Riga Movimento',
                          name_plural='Righe Movimento', caption_field='prodotto_id',
                          partition_deposito_id='deposito_id',
                          totalizer_giacenza_prodotto_deposito='mag_light.giacenza_prodotto_deposito')

Si noti che è poi possibile definire nella tabella un metodo totalize_realign_sql che si occuperà di riallineare i dati della totalizzazione alla pressione di un bottone:

def totalize_realign_sql(self,empty=False):
      if empty:
          self.empty()
          self.db.commit()
      if self.countRecords():
          return

      sql = """
          INSERT INTO mag_light.mag_light_inventario (codekey,prodotto_id,deposito_id,quantita,_refcount)
          (SELECT prodotto_id||'_'||deposito_id,
              prodotto_id,
              deposito_id,
              sum(quantita),
              count(*)

          FROM mag_light.mag_light_movimento_riga
          GROUP BY prodotto_id, deposito_id) ;
      """

      self.db.execute(sql)
      self.db.commit()

Vuoi vedere come funziona in pratica la tabella di totalizzazione? Dai un’occhiata alla tabella Giacenze disponibile nel package mag_light, di cui trovi di seguito gli allegati.


Allegati:

Autore della sezione: Davide Paci