Dalla release 2015.17.2f è possibile personalizzare le schede standard attraverso un insieme di funzioni accessibili dal pulsante Configurazione presente nel tab Strumenti della toolbar del menu principale.
Le funzioni disponibili in Configurazione sono:
- Personalizza oggetti della scheda, consente di modificare le proprietà degli oggetti presenti nella scheda, anche attraverso l’uso di script VB.NET che permettono d’agire anche su altri oggetti e sugli eventi;
- Aggiungi oggetti sulla scheda, consente d’aggiungere nuovi oggetti sulla scheda che vengono visualizzati nella parte destra;
- Report delle personalizzazioni effettuate sulla scheda, consente di visualizzare un report di tutte le modifiche effettuate sulla scheda;
- Esportazione delle personalizzazioni su file, consente d’esportare in un file tutte le personalizzazioni effettuate;
- Importazione delle personalizzazioni da file, consente d’importare da un file le personalizzazioni della scheda;
- Audit Trail delle modifiche sulla scheda, consente di visualizzare il registro cronologico delle modifiche effettuate sulla scheda dov’è memorizzata la versione salvata. Questa funzione può quindi essere utilizzata per ripristinare il layout della scheda ad una versione precedente.
Personalizzare oggetti della scheda
La funzione Personalizza oggetti della scheda consente all‘Amministratore di sistema di personalizzare ogni oggetto di una qualsiasi scheda standard, come ad esempio il campo, la casella di spunta, la casella di opzione e così via.
Nelle schede dove non è presente la barra degli strumenti si accede alla personalizzazione delle proprietà dell’oggetto attraverso il menu hamburger disponibile in alto a destra.
Il sistema apre la lista degli oggetti presenti nella scheda, dalla quale scegliere l’oggetto da personalizzare e per il quale il sistema apre la relativa scheda di personalizzazione.
I campi presenti nella scheda per personalizzare le proprietà dell’oggetto sono:
- Posizione e dimensioni del campo, area dove personalizzare i margini e le dimensioni dell’oggetto:
- Top / Left, indicano le dimensioni dei margini nel caso si desideri spostarlo;
- Altezza / Larghezza, indicano le dimensioni dell’oggetto per eventuali ridimensionamenti;
- Ruoli per i quali questo oggetto è visualizzato, riporta l’elenco dei ruoli associati alla scheda, tra i quali è possibile selezionare coloro che possono vedere l’oggetto;
- Ruoli abilitati alla modifica di questo campo, riporta l’elenco dei ruoli associati alla scheda, tra i quali è possibile definire colori che possono modificare l’oggetto;
- Aree di personalizzazione degli script:
- Script creazione, codice eseguito al momento della creazione dell’oggetto e l’assegnazione dello stato. Può essere scritto in VB.NET o C#, l’oggetto è accessibile con la variabile “this”;
- Condizione di abilitazione, codice eseguito all’apertura della scheda per stabilire se è abilitato. Può essere scritto in VB.NET o C#, l’oggetto è accessibile con la variabile “this” e lo script deve restituire un valore booleano con l’istruzione “Return”;
- Condizione di modifica, codice eseguito ad ogni cambiamento della registrazione o del documento corrente per stabilire se è modificabile (nel caso di un pulsante stabilisce se è cliccabile). Può essere scritto in VB.NET o C#, l’oggetto è accessibile con la variabile “this” e lo script deve restituire un valore booleano con l’istruzione “Return”;
- Script evento prerender, codice eseguito prima del rendering della pagina. Può essere scritto in VB.NET o C# e l’oggetto è accessibile con la variabile “this”;
- Traduzione, consente d’inserire e modificare le traduzioni delle stringhe dell’oggetto. La traduzione può essere eseguita in automatico dall’italiano ad altre lingue disponibili a sistema utilizzando il servizio di Microsoft Bing: in questo caso necessita cliccare la bandiera corrispondente alla lingua desiderata.
Inoltre, a seconda del tipo di oggetto la scheda può presentare i seguenti campi:
- Testo, indica il testo associato all’oggetto, presente quando l’oggetto è un pulsante oppure un’intestazione di un campo o casella di spunta o altro;
- Datalink, indica il nome del campo all’interno del database e le sue caratteristiche principali, come il tipo ed il numero di caratteri;
- Opzioni di formattazione del contenuto, indica che il campo ha una formattazione specifica. Qui sono presenti i campi Funzione e Maschera, che sono utilizzati solo per compatibilità di QualiWare Web con la versione QualiWare Client/Server, campi in via di progressiva dismissione perché non hanno effetto sulla versione web.
Attualmente, l’opzione di formattazione del contenuto può essere utile per i campi numerici e definire come debba essere inserito il formato del dato attraverso il campo Maschera, per esempio: 9999999.99 definisce che la grandezza dei numeri registrati e visualizzati è di 9 caratteri, dei quali 2 sono decimali, oppure inserendo 999999.999 s’imposta il numero a 3 decimali.
Aggiungere oggetti sulla scheda
La funzione Aggiungi oggetti sulla scheda apre una scheda che consente d’aggiungere ulteriori oggetti alla scheda tecnica che vengono visualizzati nella parte destra.
I campi di per l’aggiunta degli oggetti al form sono:
- Tipo, menu a tendina dove scegliere la tipologia del campo (es. Pushbotton, Memofield, Timefield, Datafield, ecc);
- Etichetta, nome d’assegnare all’oggetto d’aggiungere;
- Assegnazione proprietà, campo di script che consente d’assegnare le proprietà dell’oggetto nella forma <nome proprietà>=<valore>;
- Condizione di abilitazione, campo di script per stabilire se l’oggetto è abilitato o meno. Dev’essere utilizzata l’istruzione Return True per abilitare l’oggetto, Return False per disabilitarlo. Questa condizione ha la precedenza rispetto alle logiche standard.
Questi script sono mantenuti per garantire la retro-compatibilità con le configurazioni effettuate sulle release precedenti e se ne sconsiglia l’uso in favore rispettivamente dello script “Creazione” e “Condizione di abilitazione” definiti nella scheda Personalizza oggetti della scheda.
Per la proprietà DataLink il campo va aggiunto preventivamente alla tabella.
Esempi di codice
La possibilità di definire script per gli oggetti consente di realizzare interessanti implementazioni sulle maschere standard.
Di seguito viene riportato un esempio per mostrare come sia possibile aggiungere al workflow del modulo Non conformità la firma forte e l’Audit Trail per renderlo conforme con quanto richiesto dalle linee guida GMP (Good Manufacturing Practice).
Lo script riportato di seguito può essere inserito nell’evento script Creazione dell’oggetto Conferma, che ridefinisce il comportamento del pulsante di firma o di rifiuto del box del workflow, per richiedere la firma con nome utente e password e registrare l’evento dell’Audit Trail ad inserimento avvenuto.
dim c as QWWebControls.QWWebPushbutton=ctype(this.page,QWWebControls.QWWebPage).FindControl2("VISTO") dim form as gemanoco2=this.page dim wf as workflow = form.FindControl2("form_workflow_panel").FindControl("form_workflow") dim QWSess as QWSession=form.GetSession() Dim fasi as QWWebControls.QWWebNotebook=wf.findcontrol("NOTEBOOK1") Dim fase as string=fasi.tabs(fasi.cursel-1).Text dim op as string dim r as QWWebControls.QWWebPushbutton=ctype(this.page,QWWebControls.QWWebPage).FindControl2("RIFIUTO") ' Rimuove gli handler predefiniti removehandler c.Click, addressof wf.VISTO_onClick removehandler c.DialogClose, addressof wf.VISTO_DialogClose RemoveHandler r.Click, AddressOf wf.RIFIUTO_onClick RemoveHandler r.DialogClose, AddressOf wf.RIFIUTO_DialogClose ' Ridefinisce l'handler del Click per richiedere la firma addhandler c.Click, sub (sender as object, arg as string) dim nomi as QWWebControls.QWWebListaNominativi3 = wf.findcontrol("NOMI") dim s as dbarray=nomi.SelectedCodes() if s.size=0 orelse s(1)<>QWSess.Q95_USERCODE form.alert("Selezionare il proprio nome nella lista") return end if ' Firma forte GMP_Sign(sender,nothing,"DialogClose",true) end sub ' Ridefinisce l'handler del DialogClose per registrare l'Audit Trail! addhandler c.DialogClose, sub (sender as object, arg as string) Dim descr as string=Get_Document_Descr(QWSess,form.form_state.dmd_ref.GEMANOCO.rowset.fields("_IDDOC").value,form.form_state.dmd_ref.GEMANOCO.rowset.fields("_CODDOC").value) Dim msg as string Dim nomi as QWWebControls.QWWebListaNominativi3 = wf.findcontrol("NOMI") if not nomi.selectednode is nothing if nomi.selectednode.imageurl="" op= "Firma fase di "+fase else op="Revoca firma fase di "+fase end if end if ' Scrive sull'audit trail msg=AuditTrail_Save(QWSess,form.form_state.dmd_ref.GEMANOCO.rowset.fields("_IDDOC").value, form.form_state.dmd_ref.GEMANOCO.rowset.fields("_CODDOC").value, descr,op+" Funzione: "+arg,QWSess.Q95_USERCODE,QWSess.Q95_USERNAME) if msg="" wf.VISTO_DialogClose(sender,QWSess.Q95_USERCODE) ' Esegue l'handler standard form.Memorizza_Campi() ' Impone il salvataggio else form.alert(msg) end if end sub addhandler r.Click, sub (sender as object, arg as string) dim nomi as QWWebControls.QWWebListaNominativi3 = wf.findcontrol("NOMI") dim s as dbarray=nomi.SelectedCodes() if s.size=0 orelse s(1)<>QWSess.Q95_USERCODE form.alert("Selezionare il proprio nome nella lista") return end if ' Firma forte GMP_Sign(sender,nothing,"DialogClose", true) Dim q as qwtable dim par as assocarray = new assocarray() dim sql,err as string par("IDDOC")=form.form_state.dmd_ref.GEMANOCO.rowset.fields("_IDDOC").value par("CODDOC")=form.form_state.dmd_ref.GEMANOCO.rowset.fields("_CODDOC").value par("FASE")=fase par("NOME")=QWSess.Q95_USERCODE sql="select rifiutato from reg_reve where iddoc=:IDDOC and CODDOC=:CODDOC and NOME=:NOME and fase=(select fase from FASIREG where IDDOC=:IDDOC and descrizion=:FASE)" q=opentable(form,sql,par,false,false,err) if err="" q.rowset.first() if q.rowset.fields(1).value=0 form.session("rifiutato") = true else form.session("rifiutato") = false end if else form.alert("Errore: " + err) end if closetable(form,q) end sub addhandler r.DialogClose, sub (sender as object, arg as string) Dim descr as string=Get_Document_Descr(QWSess,form.form_state.dmd_ref.GEMANOCO.rowset.fields("_IDDOC").value,form.form_state.dmd_ref.GEMANOCO.rowset.fields("_CODDOC").value) Dim msg as string Dim nomi as QWWebControls.QWWebListaNominativi3 = wf.findcontrol("NOMI") if left (arg,8) <> "conferma" msg = "" if form.session("rifiutato") = false op="Revoca rifiuto fase di "+fase+ " da " + QWSess.Q95_USERNAME msg=AuditTrail_Save(QWSess,form.form_state.dmd_ref.GEMANOCO.rowset.fields("_IDDOC").value, form.form_state.dmd_ref.GEMANOCO.rowset.fields("_CODDOC").value, descr,op,QWSess.Q95_USERCODE,QWSess.Q95_USERNAME) end if if msg="" wf.RIFIUTO_DialogClose(sender,QWSess.Q95_USERCODE) ' Esegue l'handler standard form.Memorizza_Campi() else form.alert("Errore: " + msg) end if else msg="" if op = "" ' Non è una revoca del rifiuto, quindi va fatto ora l'AT con il motivo Dim formID, motivo_rif As String formID = CType(form, qwWebControls.QWWebPage)._uniqueID motivo_rif = form.Session(formID + "_NE_TEXT") op = "Rifiuto in fase di " + fase + " da " + QWSess.Q95_USERNAME op + = ". Motivazione: " + motivo_rif msg=AuditTrail_Save(QWSess,form.form_state.dmd_ref.GEMANOCO.rowset.fields("_IDDOC").value, form.form_state.dmd_ref.GEMANOCO.rowset.fields("_CODDOC").value, descr,op,QWSess.Q95_USERCODE,QWSess.Q95_USERNAME) end if if msg="" wf.RIFIUTO_DialogClose(sender,"conferma:"+QWSess.Q95_USERCODE) form.Memorizza_Campi() else form.alert("Errore: " + msg) end if end if form.Session.Remove("rifiutato") end sub
Nota importante
In un plugin può capitare di dovere disconnettere l’handler standard di un evento di un oggetto, ad esempio il Click o il DialogClose di un pulsante.
In questi casi può essere impossibile utilizzare RemoveHandler in quanto l’handler standard è privato.
Per effettuare l’operazione si può usare la reflection come nel seguente esempio, che disconnette l’handler dell’evento “Click” del pulsante “Elimina“.
dim c as QWWebControls.QWWebPushbutton=ctype(this.page,QWWebControls.QWWebPage).FindControl2("ELIMINA") c.gettype().GetField("ClickEvent",Reflection.BindingFlags.NonPublic or Reflection.BindingFlags.Instance).SetValue(c,nothing)
Il nome dell’evento è seguito dal suffisso “Event“, pertanto per disconnettere l’evento “DialogClose” si deve indicare “DialogCloseEvent” nel primo argomento della funzione “GetField“.
Si possono reperire altri esempi funzionanti nella sezione plug-in del forum di QualiWare, sezione con accesso riservato ai clienti titolari di Contratto di Manutenzione QIS.