Il Documento Digitale, di seguito abbreviato con DDOC, è un componente strutturato appositamente per gestire gli attributi di una classe come se fossero contenuti in un Documento formale, che viene compilato e vidimato in vari passaggi e da utenti diversi.
Il controllo permette quindi di suddividere l'anagrafica in sezioni, ognuna delle quali può essere controllata (visibile, editabile, messa in evidenza all'apertura) in maniera programmatica, in funzione dell'utente correntemente connesso, dello stato e di tutte le altre informazioni verificabili nella sessione corrente.
Dal punto di vista pratico, inserendo gli attributi in determinate sezioni, si ha la possibilità di definire delle logiche autorizzative a livello di attributo, superando il limite di Geoweb che organizza le autorizzazioni a livello di classe.
La struttura in sezioni è realizzata come un TabContainer, con le intestazioni delle sezioni poste a sinistra, in verticale. Al click su ogni sezione viene mostrato a destra lo specifico layout della sezione.
La visibilità e l'editabilità di ogni singola sezione possono essere configurate tramite l'implementazione di una class java in un file .groovy (vedi sotto).
Le sezioni del documento possono essere combinate in maniera differente formando specifici template.
All'apertura di una scheda documento, esso viene aperto con il template specificato (o con uno di default: il primo trovato, per nome in ordine alfabetico).
La scheda DDOC, presenta una intestazione fissa nella parte superiore, sopra le section, contenente uno specifico detailLayout. Questa è di fatto una section speciale, marcata con lo
specifico flag is_header (vedi sotto) e ne può esistere solo una per template.
Questa è concepita per mostrare gli attributi che sono trasversali a tutte le section, e che devono essere sempre in primo piano (per esempio codici, data creazione, stato, etc..).
Essa è sempre visibile a prescindere da quale section viene selezionata sotto.
A destra della sezione di intestazione può opzionalmente essere presente un pulsante stampa report pdf. Il nome del report, che deve essere definito a livello di classe, è specificato nei dati del Template. Se omesso non viene visualizzato alcun pulsante.
I passaggi base per configurare il DDOC sono i seguenti:
1. progettare il documento, definendo quali attributi vanno in quali sezioni, e quale deve essere la sequenza corretta
2. definire per ciascuna sezione uno o più Gruppi Attributi, nei quali incapsulare gli attributi da gestire
3. inserire i Gruppi Attributi in un Detail Layout specifico per ogni sezione
4. definire un Report di Classe (opzionale)
5. definire il Documento Digitale a livello di classe, attribuendo:
6. configurare almeno un Template del DDOC, definendo il numero e l'ordine delle sezioni, e attribuendo un Detail Layout a ciascuna di esse. Designare una delle sezioni come header, ovvero la sezione che sarà visualizzata in modo fisso, nella parte superiore in alto del controllo. Nella intestazione del template slezionare, se previsto, il Report definito al punto 4
7. configurare tra gli attributi il widget GW_DIGITAL_DOCUMENT_WIDGET, configurando tra i parametri il nome del Template
8. inserire il widget in un singolo Gruppo Attributi
9. definire un Detail Layout semplice in cui inserire il Gruppo Attributi con il DDOC, e se opportuno flaggare quest'ultimo come default
gwm_ddoc:
public Boolean isVisible(String ddocName, String templateName, String sectionName, String entityId, String entityName, String entityStatus, String gwUser, String gwGroup, Map<String, Object> gwActiveScopesMap)
public Boolean isEditable(String ddocName, String templateName, String sectionName, String entityId, String entityName, String entityStatus, String gwUser, String gwGroup, Map<String, Object> gwActiveScopesMap)
public Boolean isDefaultSelected(String ddocName, String templateName, String sectionName, String entityId, String entityName, String entityStatus, String gwUser, String gwGroup, Map<String, Object> gwActiveScopesMap)
L'utente configuratore, di volta in volta, avrà a disposizione tutti i parametri in ingresso per decidere, ritornando true o false, se abilitare o negare lo specifico permesso. All'interno dei corpi dei metodi da implementare saranno disponibili anche tutti i servizi normalmente disponibili nei groovy di classe (accedibili con notazione services.identificativo_servizio).
Se il groovy non venisse dichiarato verrà usata un'implementazione di default che abiliterà tutti i permessi. Da ricordare comunque che continuano ad operare sempre e comunque tutti i meccanismi di ACL, statica e dinamica, che sono propri del dettaglio di classe, e che verranno applicati a monte: solo in caso di esito positivo si procederà anche a valutare il responso della classe nel groovy.
Inoltre, per evitare di riscrivere nel groovy controlli doppi, se per un dato set di input isVisible() dovesse ritornare false e, per gli stessi input isEditable() dovesse invece ritornare true, la sezione non verrebbe comunque visualizzata.
Quindi va tenuto presente che il valore ritornato da isEditable() sarà valutato solo per le section per cui l’esito di isVisible() è stato positivo. Con isDefaultSelected si decide quale section il DDOC presenterà appena aperto. Anche isDefaultSelected() verrà valutato solo se isVisible() e isEditable() abbiano precedentemente ritornato esito positivo. Di default viene presentata la prima section editabile, o la prima in assoluto se sono tutte in sola visualizzazione.
gwm_ddoc_section:
gwm_ddoc_template:
gwm_ddoc_r_template_section:
ESEMPIO DI CONFIGURAZIONE GROOVY
public class TestGwDigitalDocumentConfigImpl extends com.geowebframework.transfer.objects.digitaldocument.GwDigitalDocumentConfigImpl { public Boolean isVisible( String ddocName, String templateName, String sectionName, String entityId, String entityName, String entityStatus, String gwUser, String gwGroup, Map<String, Object> gwActiveScopesMap ){ return sectionName!='test_section_5'; } public Boolean isEditable( String ddocName, String templateName, String sectionName, String entityId, String entityName, String entityStatus, String gwUser, String gwGroup, Map<String, Object> gwActiveScopesMap ){ return sectionName!='test_section_2'; } public Boolean isDefaultSelected( String ddocName, String templateName, String sectionName, String entityId, String entityName, String entityStatus, String gwUser, String gwGroup, Map<String, Object> gwActiveScopesMap ){ return sectionName=='test_section_4'; } }
Avendo disponibile il ddocWidget, è possibile fa riferimento alle seguenti proprietà e function esposte:
{ gwid: 123, fkDdoc: 456, name: 'section_name', label: 'section_label', detailLayoutName: 'section_detailLayoutName', isHeader: true, isVisible: true, isEditable: true, isDefaultSelected: false }
[ { gwid: 123, fkDdoc: 456, name: 'section_name', label: 'section_label', detailLayoutName: 'section_detailLayoutName', isHeader: true, isVisible: true, isEditable: true, isDefaultSelected: false }, { gwid: 123, fkDdoc: 456, name: 'section_name', label: 'section_label', detailLayoutName: 'section_detailLayoutName', isHeader: false, isVisible: true, isEditable: true, isDefaultSelected: true } ]
{ gwid: 123, fkDdoc: 456, name: 'ddoc_section_name', label: 'ddoc_section_label', detailLayoutName: 'ddoc_section_detailLayoutName', isHeader: false, isVisible: true, isEditable: true, isDefaultSelected: true }
Si potrebbe volere, per esempio, in un'azione di dettaglio pronto, eseguire delle operazioni solo se una certa ddocSection risultasse editabile in quel momento (in base alla valutazione dinamica del grrovy).
var ddocWidget = detailContainer.getGwWidget({name: 'ddoc_widget'}); //detailContainer provided var name = 'section_name'; //known var isEditable = ddocWidget.isDDOCSectionEditable(name); if(isEditable){ //do stuff }
var ddocWidget = detailContainer.getGwWidget({name: 'ddoc_widget'}); //detailContainer provided var name = 'section_name'; //known var isVisible= ddocWidget.isDDOCSectionVisible(name); if(isVisible){ //do stuff }
Dalla versione 4.6.9 (issue #1070), è stato rilasciato anche il widget gwDigitalDocument2 (DDOC2), simile al gwDigitalDocument, con la stessa struttura dei metadati, e stessi parametri xml widget, ma diversa forma grafica e comportamento.
Al posto delle sezioni individuate dal tab, c'è sempre il documento pdf in primo piano.
La report jasper, può utilizzare il parametro booleano IS_GW_RECORD_EMPTY (che viene passato a true nel caso il record geoweb non esista ancora) al solo fine di garantire in maniera opportuna la visualizzazione di un documento digitale vuoto, anche in assenza di record.
Scompare l'apposito button di apertura report nella sezione header.
La sezione Header, anche se non contiene più il button della report e le info di intestazione, va comunque dichiarata, e nel caso nascosta imponendo un altezza di 0px al relativo layout. In caso contrario, non viene lanciato l'evento di dettaglio pronto.
Le intestazioni delle Section (i vecchi selettori dei tab, che prima comandavano le parti di dettaglio [i detailLayout] impostate per la sezione), ora sono button. La loro stilizzazione attuale è rimasta la medesima, ma senza l'esplicitazione del concetto di ultimo selezionato
Al click delle intestazioni delle Section, solo in caso di permesso di edit, ora vengono aperti dei floatingPane modali, contenenti le medesime parti di dettaglio.
In caso di solo permesso di visualizzazione, al click sulla intestazione di Sezione avviene lo scroll sul documento pdf (tramite configurazione dei bookmarks (hyperlink + bookmark level) in IReport 5 / Jaspersosft Studio 6) A tale proposito si prega di visionare il video https://www.youtube.com/watch?v=XkpJq-P2Gko
I permessi edit/visualize derivano, come prima, dal risultato dinamico computato dall'esecuzione del groovy configurato.