Lezione 7: Miglioriamenti fattura

In questa lezione miglioreremo la form della fattura.

Inoltre vedremo come assegnare a un nuovo record valori di default e valori basati su contatori progressivi automatici.

Testata fattura

Al termine della lezione precedente abbiamo lasciato la form della fattura ancora molto grezza ed incompleta.

Procediamo ora a dividere la parte superiore in una zona di sinistra ed una di destra, e per far ciò utilizzeremo un borderContainer. In quella di sinistra posizioneremo i campi protocollo, data, totale_imponibile, totale_iva e totale_fattura. Questi ultimi tre campi avranno l'attributo readOnly=True dal momento che vengono calcolati automaticamente dai trigger.

La parte sinistra che accoglie i campi appena visti viene inserita in un elemento roundedGroup che incornicia un gruppo di campi con un titolo.

Nella parte di destra inseriremo un linkerBox per la selezione del cliente.

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

def fatturaTestata(self, bc):
    left = bc.roundedGroup(title='Dati fattura',
                            region='left', width='300px')
    fb = left.formbuilder(cols=1, border_spacing='4px')
    fb.field('protocollo')
    fb.field('data')
    fb.field('totale_imponibile', readOnly=True)
    fb.field('totale_iva', readOnly=True)
    fb.field('totale_fattura', readOnly=True)

    bc.contentPane(region='center').linkerBox('cliente_id', margin='2px')

Il linkerBox

Fino ad ora per selezionare il cliente avevamo usato un widget chiamato dbselect che è un widget che viene inserito in modo automatico dalla funzione field ogni volta che si riferisce ad un campo in relazione. Infatti se un formbuilder è associato ad una tabella di database l'elemento field riconosce dal nome del campo il widget più adatto per l'input a seconda del tipo di dato.

La dbselect fa egregiamente il suo lavoro e ci consente di selezionare il cliente desiderato. Non ci consente però di richiamare alla vista i suoi dati anagrafici ed evenutalmente modificarli se necessario.

Per questo esiste il component linkerBox, che si compone di una dbselect e di una zona template per visualizzare i dati del record selezionato opportunamente formattati. Per un approfondimento sul funzionamento dei widget dbselect e linkerbox vi rimandiamo alla spiegazione fornita nel Manuale utente di Genropy.

Andiamo ora a vedere come si presenta la pagina della fattura e notiamo che in alto a destra c'è un riquadro che ci avvisa che non esiste ancora un template collegato.

Dal momento che il nostro utente admin ha i permessi necessari, con shift + doppio click andiamo a modificare il template.

Il templateEditor

Per creare il template richiesto dal linkerBox utilizzeremo uno strumento chiamato templateEditor che si apre in una palette e ci consente di svolgere alcuni compiti.

In primo luogo dall'albero nella colonna di sinistra della palette trasciniamo i campi che vorremmo usare nella griglia delle variabili in uso. Possiamo trascinare campi dalla tabella principale (cliente in questo caso), o da altre tabelle collegate. Il sistema provvederà automaticamente ad effettuare le query necessarie in modo da darci i dati richiesti.

Andiamo poi nella pagina del template e trasciniamo le variabili precedentemente selezionate, formattandole a nostro gradimento e inserendo le parti di testo che desideriamo.

Salvare il template dal templateEditor, andrà a creare nella directory resources/tables/cliente/tpl il file default.xml (vedi allegato).

Miglioriamo il linkerBox

Per selezionare il cliente abbiamo dovuto cliccare sulla piccola freccia in alto a destra nel linkerBox. Sarebbe stato preferibile per l'utente trovare il campo già usabile e quindi nei parametri del linkerBox aggiungiamo openIfEmpty=True. Dal momento poi che desideriamo che non si possa cambiare cliente alla fattura una volta salvata aggiungiamo anche newRecordOnly=True.

bc.contentPane(region='center').linkerBox('cliente_id',
                                              margin='2px',
                                              openIfEmpty=True,
                                              newRecordOnly=True)

defaultValues

Al caricamento di una nuova fattura desideriamo assegnare la data di lavoro come data fattura. Per fare questo andiamo a modificare il modulo di model fattura.py, ed aggiungiamo il metodo defaultValues. Questo deve restituire un dict che ha come chiavi i campi e come valori i loro default.

def defaultValues(self):
      return dict(data=self.db.workdate)

Gestione automatica contatori

Nelle applicazioni gestionali è prassi frequente assegnare a dei documenti dei contatori progressivi per avere un riferimento univoco. Potremmo avere contatori per fatture cliente, note credito, documenti di trasporto, ordini ricevuti e via dicendo.

Gestire questi contatori, verificando che sia rispettata la cronologia e che non si creino salti di numerazione è un compito noioso e che richiede molta pazienza.

In Genropy esiste un sottosistema di gestione contatori che fa capo al package adm che abbiamo incluso nel progetto.

Per indicare che la nostra fattura desidera usare il gestore dei contatori definiamo un metodo counter_protocollo che ci dovrà restituire i parametri di gestione del contatore in questo contesto. Si tratta di un metodo hook formato dal prefisso counter seguito dal nome della colonna che utilizzerà il contatore.

In particolare abbiamo qui deciso che il protocollo ovvero, il numero di fattura, sarà prefissato dalla lettera F (per distinguerlo ad esempio da una bolla che potrebbe usare la lettera B), conterrà poi le ultime 2 cifre dell'anno e di seguito un numero di 6 cifre.

Gli elementi detti sono definiti in un un parametro stringa format, secondo una sintassi dove si usano degli elementi placeholder preceduti da $.

  • $K è una parte di prefisso che viene riempita a partire dal parametro code
  • $YY (oppure potrebbe essere $YYYY o $MM o $DD o una loro combinazione) è l'elemento ottenuto dalla data di riferimento passata nel parametro date
  • $N rappresenta il numero restituito dal contatore
def counter_protocollo(self, record=None):
      ##Formato desiderato F19/000001

      return dict(format='$K$YY/$NNNNNN', code='F', period='YY',
                  date_field='data', showOnLoad=True, recycle=True)

Il gestore dei contatori è anche in grado, per una nuova fattura, di mostrarci il numero che verrà poi assegnato al salvataggio. Per fare questo utilizziamo il parametro showOnLoad .

Se desideriamo che in caso di cancellazione il numero disponibile sia riutilizzato per evitare buchi di numerazione, utilizziamo il parametro ricycle.

Collaudo finale

Possiamo ora vedere come all'aggiunta di una nuova fattura il numero di protocollo venga assegnato in modo automatico. E potremo pertanto mettere anche questo campo readOnly=True.

Hint

Nel video è anche mostrato come si effettuano le azioni di riallineamento dei contatori. Ma se avete eseguito correttamente le istruzioni finora riportate non dovrebbe essere necessario effettuare questa azione. A meno che non abbiate inserito delle fatture di prova.

Attachments: