Modulo kanban per Tryton

Introduzione

Tryton è un framework three-tier, multi piattaforma e multi database rilasciato su licenza GPL3, il cui core garantisce scalabilità, modularità e stabilità. Tryton è un framework su cui può essere scritta una soluzione di business completa, le sue caratteristiche principali sono:

  • persistenza dei dati
  • modularità
  • autenticazione
  • access control list
  • gestione concorrenza nell’accesso ai dati
  • workflow
  • report engine
  • web service
  • internazionalizzazione

Su questo framework sono stati sviluppati una gran quantità di moduli verticali orientati alla gestione aziendale e non solo. Fra questi:

  • Contabilità Generale
  • Fatturazione
  • Gestione Ciclo Attivo
  • Gestione Ciclo Passivo
  • Contabilità Analitica
  • Gestione Magazzino
  • Gestione della Produzione
  • Gestione Progetti
  • Gestione Lead e Opportunità

Oggi la nostra attenzione verrà dedicata al modulo di project management ed in particolar modo verrà introdotto un nuovo widget, sviluppato da innoviù Srl, per la gestione della vista kanban.

Funzionalità Kanban

La vista kanban del progetto consente la gestione dei task aziendali in modalità pull: i task vengono trascinati verso destra e percorrono le varie fasi del progetto fino alla loro conclusione (ad esempio: analisi, sviluppo, test, deployment, chiusura). Ad ogni utente vengono assegnati diversi task che vengono via via lavorati e portati alla fase di completamento; questo approccio è molto conveniente in ambienti in cui, ad esempio, è necessaria la gestione di avanzamento dei task di trouble ticketing.

Comportamento del Widget Kanban

Tryton ha un sistema molto potente di visualizzazione grafica dei dati basata sulla libreria grafica cairo. Purtroppo la gestione dei task grafici risulta molto complessa in gtk2, libreria ui su cui il client di tryton è sviluppato, e pertanto si è deciso di implementare un nuovo tipo di widget che integra un browser all’interno della finestra gtk2 con la libreria webkit. Questa scelta offre un notevole vantaggio in termini di flessibilità della funzionalità e nell’utilizzo delle librerie di sviluppo web.

Descrizione del widget

Partendo dall’esempio riportato nel video l’utente apre la vista kanban del progetto, il sistema genera la view webkit e richiede al server tryton la pagina html. Una volta caricata la pagina html viene eseguito il js interno al codice python del client che passa alla pagina: l’id del record corrente, l’id utente, il database utilizzato e la stringa di autenticazione temporanea con cui effettuare le chiamate al server. A questo punto tutta la logica è spostata sulla definizione del javascript caricato nella pagina. In questo caso partendo dall’id del progetto vengono caricati tutti i task associati con delle search al server e vengono disposti nella pagina con vista kanban.

Utilizzando la funzionalità drag and drop dei cartellini kanban ad ogni passaggio viene inviata una funzione write per modificare lo stato del task.

Un aspetto molto interessante di questo widget è che il codice javascript eseguito può richiamare il codice python del client mediante l’ascolto di quest’ultimo dell’esecuzione di alcuni eventi nella pagina. Nel caso specifico, come si evince dal video, al passaggio del task all’ultimo stato, viene aperta la finestra di tryton per consentire all’utente di inserire le ore lavorate in totale ed una breve descrizione sul lavoro compiuto per il task.

Struttura Modulo con Widget BrowserBox

kanban project

Il modulo che implementa un campo browserbox ha la struttura riportata nell’immagine sopra.

Nella cartella web sono inseriti tutti i file per la gestione dei css, js, e html. Il contenuto del modulo web deve essere spostato nella cartella var/www del server tryton. è importante notare che l’html deve stare in una cartella con il nome del modello in cui il campo con widget browserbox è inserito ed il file html deve avere lo stesso nome del campo.

La vista form invece è così definita:

<form string="My Tasks">
	<label name="employee"/>
	<field name="employee"/>
	<notebook>
    	<page string="Kanban" id="kanban">
            	<field name="kanban" widget="browserbox"/>
    	</page>
	</notebook>
</form>

il campo kanban ha come widget “browserbox”

Il campo kanban è definito nel modello project.work.employee nel file kanban.py

class EmployeeWork(ModelSQL, ModelView):
	'Employee Work'
	__name__ = 'project.work.employee'

	employee = fields.Many2One('company.employee', 'Employee',
                           	select=True, readonly=True)
	kanban = fields.Function(fields.Text('Kanban Data'),
                         	'get_data', setter='set_kanban')

	@classmethod
	def __setup__(cls):
    	super(EmployeeWork, cls).__setup__()
def get_data(self, name):
    	records = {'stages': [], 'tasks': {}}
    	Project = Pool().get('project.work')
    	projects = Project.search([('type', '=', 'project'),
                               	('active', '=', True)],
                              	order=[('sequence', 'ASC')])
    	for project in projects:
        	for child in project.children:
            	if child.type == 'task' and child.state == 'opened' and \
                	(child.employee is None or
                 	child.employee == self.employee):
                	#TODO check for subprojects here
                	records['tasks'][child.id] = [child.parent.work.name +
                                              	'\n' + child.work.name,
                                              	child.stage.code,
                                              	child.work.id]
    	Stage = Pool().get('project.stage')
    	stage_ids = Stage.search((1, '=', 1), order=[('sequence', 'ASC')])
    	for stage_id in stage_ids:
        	stage = Stage(stage_id)
        	records['stages'].append((stage.name, stage.code, stage.id))
    	return json.dumps(records, sort_keys=True)

Il campo Function kanban di tipo Text (browserbox eredita infatti da questo campo) fa riferimento alla funzione get_data. Quest’ultima restituisce il dump json di un dizionario: del tipo {‘stages’: [], ‘tasks’: {}}. Questa funzione è sostanzialmente libera e può contenere tutte le informazioni che si vogliono stampare a video nel box html.

il javascript all’interno della pagina html richiamerà il server con i dati passati dal codice python del widget (database, user_id, session_id, record_id)

 var args = {
        	'method': 'model.project.work.employee.read',
        	'params': [user_id, session_id].concat([[record_id],field_names,{}])
        	};

field_names è una lista in cui è presente solo il campo kanban 

var field_names = [];
field_names.push('kanban')

La funzione create_kanban andrà a chiamare il server con i dati inseriti e farà il parsing della risposta valorizzando sia i vari stage che i task associati. A questo punto verrà costruita la vista kanban con tutti i dati passati dal server tryton.

Una funzionalità molto importante del widget è rappresentata dalla possibilità di aprire finestre in tryton passando dalla dashboard html appena creata. Richiamando infatti la funzione

function open_timesheet_line_form(response) {
   		 send("button-clicked", ['timesheet.line:' + response.result]);
    	}

(dove response.result è l’id della linea da richiamare) il widget, che rimane in ascolto degli eventi caricati sulla pagina, attiverà la funzione output

def output(self, data):
    	ctx = {}
    	ctx.update(rpc.CONTEXT)
    	ctx['active_test'] = False
    	model, id = data[0].split(':')
    	ids = [int(id),]
    	return Window.create(False, model, ids, [],
        	mode=['form', 'tree'], context=ctx)

che aprirà il tab corrispondente nel client.

Multi-piattaforma

Pywebkitgtk non è stato compilato per windows a causa di problemi del componente con alcune funzionalità sotto il sistema operativo di microsoft per integrare direttamente la compenente explorer all’interno della finestra gtk. Lo sviluppo in tal senso è ancora in fase alpha.

Passi successivi

Il passo successivo sarà quello di tradurre le funzionalità presenti nel browserbox sotto client python su iFrame html per Sao. Ovviamente è in corso un refactoring continuo per garantire tutte gli aspetti di sicurezza del componente. Al momento il colore dello stadio del task è inserito nel codice css, stiamo lavorando per poter inserire il colore direttamente dal modello dello stadio.

Conclusioni

Il widget browserbox è stato concepito per permettere agli sviluppatori di inserire dei grafici o delle funzionalità di riepilogo su record differenti. Ad esempio creando un field browserbox per un party è possibile implementare una pagina con diversi grafici dinamici e interattivi su tutta la storia di un’anagrafica e non solo su alcuni modelli correlati. Questo nuovo widget può essere richiamato facilmente in un proprio modulo creando un field tipo text e inserendo nella view widget=”browserbox”, sarà quindi cura dello sviluppatore creare le pagine html di interfacciamento (la pagina si deve trovare in www_path/module_name/field_name.html).

Download