Lezione 5: Fattura e righe fattura

In questa lezione verranno create le tabelle fattura, fattura_riga e le rispettive risorse.

Tabella fattura

Creiamo ora la tabella fattura.py e mettiamo la colonna protocollo (ovvero un numero progressivo che dovrà ripartire ad ogni anno), cliente_id per collegare la tabella cliente, e poi le colonne data, totale_imponibile, totale_iva e totale_fattura.

class Table(object):
    def config_db(self, pkg):
        tbl = pkg.table('fattura', pkey='id',
                      name_long='Fattura', name_plural='Fattura', caption_field='protocollo')
        self.sysFields(tbl)
        tbl.column('protocollo', size='10', name_long='Protocollo')
        tbl.column('cliente_id', size='22', group='_', name_long='Cliente'
                 ).relation('cliente.id',
                            relation_name='fatture',
                            mode='foreignkey', onDelete='raise')
        tbl.column('data', dtype='D', name_long='Data')
        tbl.column('totale_imponibile', dtype='N',
                 name_long='Totale imponibile')
        tbl.column('totale_iva', dtype='N', name_long='Totale Iva')
        tbl.column('totale_fattura', dtype='N', name_long='Totale')

Tabella fattura_riga

Procediamo quindi a creare la tabella fattura_riga definendo le colonne necessarie.

class Table(object):
    def config_db(self, pkg):
        tbl = pkg.table('fattura_riga', pkey='id',
                      name_long='Fattura riga', name_plural='Fattura righe')
        self.sysFields(tbl)
        tbl.column('fattura_id', size='22', group='_',
                 name_long='Fattura'
                 ).relation('fattura.id', relation_name='righe', mode='foreignkey', onDelete='cascade')
        tbl.column('prodotto_id', size='22', group='_', name_long='Prodotto').relation(
            'prodotto.id', relation_name='righe_fattura', mode='foreignkey', onDelete='raise')
        tbl.column('quantita', dtype='I',
                 name_long=u'Quantità', name_short='Q.')
        tbl.column('prezzo_unitario', dtype='N',
                 name_long='Prezzo unitario', name_short='P.U.')
        tbl.column('aliquota_iva', dtype='N',
                 name_long='Aliquota iva', name_short='Iva')
        tbl.column('prezzo_totale', dtype='N',
                 name_long='Prezzo totale', name_short='P.T.')
        tbl.column('iva', dtype='N', name_long='Tot.Iva')

In particolare la colonna fattura_id rappresenta il collegamento con la fattura. Notiamo che nel descrivere la relazione aggiungeremo l'attributo onDelete='cascade' per indicare che in caso di cancellazione della fattura le righe fattura dovranno parimenti essere cancellate.

Aggiungiamo poi prodotto_id ma, questa volta, nella relazione useremo onDelete='raise' per indicare che il sistema dovrà impedire la cancellazione del record prodotto, se questo è referenziato da una riga fattura.

Creazione tabella tipo_iva

Per tenere conto del possibile diverso trattamento fiscale dei vari prodotti provvediamo a modificare la table prodotto aggiungendo la colonna tipo_iva_codice

tbl.column('tipo_iva_codice', size=':5', group='_', name_long='!![it]Tipo iva').relation(
        'tipo_iva.codice', relation_name='prodotti', mode='foreignkey', onDelete='raise')

in relazione con l'apposita tabella di lookup tipo_iva che provvediamo a creare, come già visto nella Lezione 3

class Table(object):
    def config_db(self, pkg):
        tbl = pkg.table('tipo_iva', pkey='codice', name_long='Tipo iva',
                  name_plural='Tipi iva', caption_field='descrizione', lookup=True)

        self.sysFields(tbl, id=False)

        tbl.column('codice', size=':5', name_long='Codice')
        tbl.column('descrizione', name_long='Descrizione')
        tbl.column('aliquota', dtype='N', name_long='Aliquota')

Inoltre modificheremo la form del prodotto per aggiungere il campo tipo_iva

fb.field('tipo_iva_codice', validate_notnull=True)

Quindi dopo aver

  • riallineato il database
  • resettato il server

Procediamo a popolare la tabella tipo_iva ed assegnare i valori di tipo_iva_codice ai prodotti già creati.

Form fattura

Adesso facciamo generare le risorse th_fattura e th_fattura_riga e modifichiamole per migliorarle.

Come già visto precedentemente per il cliente, usiamo un BorderContainer per dividere la form in 2 regioni: quella superiore che conterrà i dati di testata e quella centrale dove verranno caricate le righe fattura.

Creiamo quindi il metodo fatturaTestata che andrà a definire la form in un contentPane posto nella regione superiore. Eliminiamo quindi i campi relativi ai totali, infatti questi saranno calcolati in modo automatico.

def th_form(self, form):
    bc = form.center.borderContainer()
    self.fatturaTestata(bc.contentPane(region='top', datapath='.record', height='150px'))
    self.fatturaRighe(bc.contentPane(region='center'))

def fatturaTestata(self, pane):
    fb = pane.formbuilder(cols=2, border_spacing='4px')
    fb.field('protocollo')
    fb.field('cliente_id')
    fb.field('data')

Le righe della fattura

Definiamo poi il metodo fatturaRighe. In questo contentPane inseriremo il component inlineTableHandler che è un gestore completo di tabella con editing in linea dei dati. Questo component si occuperà di gestire la tabella, ci darà modo di aggiungere righe, cancellarle e modificarle.

def fatturaRighe(self, pane):
   pane.inlineTableHandler(relation='@righe', viewResource='ViewFromFattura')

In seguito torneremo ampiamente sui tableHandler ma per il momento ci limitiamo a crearlo dando come parametro la relazione relation='@righe' che deve essere seguita al fine di riempire la griglia con le righe relative al record di fattura corrente.

Inoltre mettiamo anche un attributo viewResource='ViewFromFattura' per specificare che useremo una classe di view della risorsa th_fattura_riga creata appositamente per essere visualizzata dalla form di fattura.

la classe ViewFromFattura

Procediamo a modificare il modulo th_fattura_riga creando la classe ViewFromFattura.

Nella struttura eliminiamo la colonna fattura_id in quanto non sarà necessario mostararla. Andiamo poi ad aggiungere sulle colonne prodotto_id e quantita l'attributo edit=True per indicare che desideriamo editare le celle corrispondenti.

class ViewFromFattura(BaseComponent):

    def th_struct(self, struct):
        r = struct.view().rows()
        r.fieldcell('prodotto_id', edit=True)
        r.fieldcell('quantita', edit=True)
        r.fieldcell('prezzo_unitario')

Primo collaudo

Procediamo a collaudare la fattura modificando prima il menu

fatturazione.thpage(u"Fatture", table="fatt.fattura")

e caricando il primo record. Per il momento non ci sono ancora automatismi e quindi metteremo manualmente un numero di fattura e la data.

Sceglieremo quindi un cliente e con il bottone + della vista delle righe creeremo una riga nella quale scegliamo un prodotto e mettiamo una quantità. Salviamo quindi la fattura con la riga creata. Nel prossimo capitolo vedremo come migliorare la nostra pagina per la creazione delle fatture.

Attachments: