L'Approval Workflow è uno dei workflow presenti nell’installazione di default di Office Sharepoint Server 2007. L'inserimento dei workflow come features all'interno di sharepoint ha dato sicuramente un notevole tocco di novità al prodotto e i risultanti benefici possono essere veramente utili. Il workflow in questione, infatti, offre funzionalità avanzate per quanto riguarda l'approvazione di un generico oggetto; dico generico perché il flusso d'approvazione può essere legato sia agli elementi di una document library, che agli elementi di una lista semplice (come può essere un calendario o una lista di news), sia alla modifica del contenuto di una content page (in siti sharepoint con le funzionalità di publishing attivate).
Queste le caratteristiche del workflow:- le operazioni di approvazione sono divise in task
- possibilità di gestione del flusso in modalità parallela o in serie
- modalità di assegnazione dei task a singoli utenti o a gruppi di utenti
- possibilità di delegare l'esecuzione di un task ad un altro utente (o gruppo)
- possibilità di riassegnare un task ad un altro utente (o gruppo)
- possibilità di scegliere se terminare il workflow al primo rifiuto (in modalità multi-task)
- possibilità di aggiornare le informazioni sullo stato dell’oggetto al termine del workflow
- sistema per aggiungere un voto all'oggetto
- possibilità di scegliere se terminare il workflow se il contenuto dell’oggetto viene modificato
Viste tutte queste funzionalità, direi che possiamo essere tutti d'accordo nel dire che il sistema di approvazione di default di Sharepoint Services è nettamente ormai superato dall'introduzione di questo workflow.
Per utilizzarlo all’interno di una lista Sharepoint, non bisogna far altro che andare sui list settings della lista scelta, selezionare la voce Workflow Settings e scegliere l'operazione di aggiunta di un nuovo workflow. Qui verrà mostrata una pagina contenente tutti i workflow installati nella site collection padre e tutti i settaggi per una corretta installazione del workflow. Queste informazioni riguardano il nome della lista dei task e della lista di history e il modo di avviamento del workflow. Sharepoint permette di avviare un workflow in due modi:- all'aggiunta di un nuovo item
- alla modifica di un item esistente all’interno della lista
Figura 1 - Pagina di aggiunta di un nuovo workflow
Una volta scelti i parametri di installazione, la procedura guidata vi porterà alla pagina di configurazione del workflow scelto. Nel nostro caso, tale pagina conterrà tutti i campi relativi alle proprietà di configurazione dell'Approval Workflow.
Figura 2 - Pagina per la configurazione dei valori di default dell'Approval Workflow
Scelti i valori di default, abbiamo completato correttamente la procedura di installazione e possiamo iniziare ad utilizzare tutte le funzionalità offerte da questo potente flusso di approvazione dei contenuti.
Personalizzazione dell’avviamento del workflow
Anche se il workflow di approvazione in questione sembra soddisfare ogni nostro desiderio, proviamo a pensare ad uno scenario in cui, per esempio, abbiamo la necessità di settare un gruppo di approvatori differente per ogni oggetto di una nostra lista, necessità tra l'altro decisamente reale in ambienti aziendali di grosse dimensioni, dove contenuti appartenenti ad una stessa categoria, devono essere approvati da divisioni diverse.
Per far ciò, dobbiamo cercare di modificare i parametri di avviamento di default del workflow e scrivere un event handler personalizzato che, alla creazione di un nuovo item all'interno della lista (o magari anche in fase di modifica), faccia partire il nuovo flusso di approvazione.
Per avviare "a mano" un workflow all’interno di Sharepoint, ci possiamo avvalere dell'utilizzo del metodo StartWorkflow della classe SPWorkflowManager (namespace Microsoft.Sharepoint.Workflow). Tale metodo accetta come parametri:- l'item al quale allegare il workflow
- il template del workflow da utilizzare
- un valore di tipo boolean a indicare se il workflow deve partire in automatico o meno
- i parametri di inizializzazione, in formato XML
Questi parametri, devono essere passati alla form Infopath di init del workflow; è proprio da tale form che noi andremo a prelevare le strutture dati per inizializzare il flusso e permetterne l'avviamento.
Queste le operazioni per la creazione delle strutture dati a partire dalla form di init del workflow:- Raggiungere il seguente percorso sul server c:\ProgramFiles\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES\ReviewWorkflows\Forms\
- Copiare il file ReviewRouting_Init_1033.xsn (form Infopath di init del workflow)
- Aprire la form con Infopath facendo click con il tasto destro del mouse sul file e selezionando la voce "design" del menu contestuale
- Selezionare il menu File > Save as source files
- Scegliere il percorso in cui salvare i file
- Chiudere la form
Figura 3 - Form Infopath di inizializzazione del workflow
In questo modo, Infopath ha creato il file schema relativo alle strutture dati di inizializzazione dell'Approval Workflow. Ora questo schema, va trasformato in una classe .NET in modo tale da poterlo utilizzare all'interno del nostro event handler. Per effettuare questa trasformazione ci avvaliamo dell'utilizzo dell'utility XSD, inserita con l'installazione di default dell'intero SDK relativo al .NET Framework 2.0 (per maggiori informazioni sull'utilizzo di tale utility, visitare la documentazione on-line).
Dal prompt dei comandi, spostarsi quindi nella directory dove avete salvato l'XML schema ed eseguire il comando:
Verrà così creata la classe myschema.cs, classe da importare nel progetto Visual Studio per la creazione dell'event handler di avviamento personalizzato del workflow di approvazione.
Ecco il risultato dell’esecuzione dell'utility:
Figura 4 - Esecuzione dell'utility XSD
Ora, è il momento di scrivere l'event handler. Questo il codice dell’evento ItemAdded:
public class StartApprovalWorkflow : SPItemEventReceiver
{
public override void ItemAdded(SPItemEventProperties properties)
{
try
{
using (SPWeb web = properties.OpenWeb())
{
//prelevo il nome della società scelta
Guid listID = properties.ListId;
int itemID = properties.ListItemId;
SPListItem item = web.Lists[listID].GetItemById(itemID);
//prelevo il valore del campo approvatori
string approvatori = item["Approvatori"].ToString();
//prelevo la lista corrente
SPList list = web.Lists[properties.ListTitle];
//prelevo il template del workflow associato alla lista
SPWorkflowAssociation associationTemplate =
list.WorkflowAssociations.GetAssociationByBaseID(
new Guid("C6964BFF-BF8D-41ac-AD5E-B61EC111731C"));
foreach (SPWorkflowAssociation ass in list.WorkflowAssociations)
{
if (associationTemplate == null && ass.Name.ToLower() == "approvazione")
associationTemplate = ass;
}
if(associationTemplate == null)
WriteError("Association template not found");
//START DEL WORKFLOW A MANO !
web.Site.WorkflowManager.StartWorkflow(properties.ListItem,
associationTemplate,
getInitXmlString(approvatori, web),
true);
}
}
catch (Exception exe)
{
WriteError(exe.Message);
}
}
//...
}
L'implementazione dell'evento ItemAdded, come potete vedere, non è particolarmente complicata; l'unico punto cui porre attenzione è il recupero del template del workflow associato alla lista. Possiamo recuperarlo o attraverso il suo ID (visibile nella pagina dei workflow settings della lista), oppure scorrendo la collezione di tutte le associazioni della lista e prelevando quella con il nome da noi scelto. Si, perché prima di creare questo event handler, va aggiunto il workflow alla lista, come spiegato nel primo paragrafo dell’articolo.
Vediamo ora, l'implementazione del metodo getInitXmlString, metodo che fa il parsing del valore del campo "Approvatori" per recuperare gli utenti o i gruppi scelti per l’approvazione, crea le strutture dati per l'inizializzazione del workflow e le serializza in modo tale da passarle nel formato corretto (XML) al metodo StartWorkflow.
public string getInitXmlString(string approvatori, SPWeb web)
{
myFields data = new myFields();
//ogni approvatore arriva secondo questo formato:
//<ID>#;<Nome>
string[] approvers = approvatori.Split(';');
int count = 0, resto = 0, index = 0;
data.Reviewers = new Person[approvers.Length / 2];
foreach (string a in approvers)
{
int risultato = Math.DivRem(count, 2, out resto);
if (resto == 0 || count == 0)
{
string a1 = a.Trim();
a1 = a1.Replace("#", "");
//creo un nuovo approvatore logico
Person person = new Person();
try
{
//provo a vedere se è un utente
SPUser user = web.Users.GetByID(Int32.Parse(a1));
person.AccountType = "User";
person.AccountId = user.LoginName;
person.DisplayName = user.Name;
}
catch
{
//altrimenti è un gruppo
SPGroup group = web.Groups.GetByID(Int32.Parse(a1));
person.AccountType = "Group";
person.AccountId = group.Name;
person.DisplayName = group.Name;
}
//aggiungo l'approvatore all'elenco degli approvatori
data.Reviewers[index] = person;
index++;
}
count++;
}
//proprietà che vanno bene per tutti i workflow
data.Title = "Approvazione";
data.DefaultTaskType = "1";
data.CreateTasksInSerial = false; //creo i task in parallelo
data.CreateTasksInSerialSpecified = false;
data.AllowDelegation = true; //permetto la delegazione di un task
data.AllowChangeRequests = true; //permetto le richieste di cambiamento
data.StopOnAnyReject = true; //stoppo il workflow al primo rifiuto
data.SetMetadataOnSuccess = false;
data.ApproveWhenComplete = false;
data.Voting = false; //non permetto i voti
data.InitLock = false;
data.MetadataStop = false;
data.ItemChangeStop = true;
data.GroupTasks = true; //raggruppo i task
data.GroupTasksSpecified = true;
data.WantedTasks = "true";
//serializzo le mie strutture dati per passarle al workflow
using (MemoryStream stream = new MemoryStream())
{
XmlSerializer serializer = new XmlSerializer(typeof(myFields));
serializer.Serialize(stream, data);
stream.Position = 0;
byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, bytes.Length);
return Encoding.UTF8.GetString(bytes);
}
}
Ora che il nostro event handler è creato, dobbiamo inserire, la libreria che lo contiene, all'interno della GAC del server (per far questo, la libreria deve essere segnata con una chiave). Poi, dobbiamo scrivere una console application, per registrare l'event handler su sharepoint e legarlo all'evento ItemAdded della lista in cui abbiamo la necessità di utilizzare il workflow di approvazione. La console application in questione, è presente nel download allegato all’articolo.
Conclusioni
In questo articolo abbiamo visto quali sono le caratteristiche del nuovo workflow di approvazione inserito in MOSS 2007. Inoltre, abbiamo visto il modo in cui possono essere create tutte le strutture dati utili a inizializzare il workflow a mano e farlo partire all'interno delle nostre procedure personalizzate. Nell'esempio abbiamo scelto di implementare un event handler, la stessa operazione la possiamo comunque effettuare da una web part o da pagine aspx.
In questo modo abbiamo ancora più controllo su un sistema di approvazione gia molto potente.
Inoltre, la stessa tecnica di creazione delle strutture dati necessarie per l'avviamento di un workflow proprio di Sharepoint, può essere applicata a tutti gli altri flussi installati e permettervi di attuare le vostre personalizzazioni con grande facilità.
|
|
|