Loading

Workflow Approval Delegation

In my previous post I presented the approach for configuring workflow approvers on document level, so many documents could reuse the same workflow, having different approvers. In this post I want to suggest minor improvement for the approval process - delegation.

There are situations, especially during summer, or winter holidays, when many people take vacation to have a good time with their family and friends. Of course all we really like this period as well as having vacation. However, this might significantly slow down work processes. Let's imagine there is a document, that needs to be approver by 5, or even 10, persons sequentially, but 2 or 3 of those approvers are on vacation - this process might take 3-5 weeks instead of 3-5 days. In some case this is just unacceptable!

So how can we improve this process and allow pages/content to move smoothly through a workflow? Approval delegation should address this issue. Basically there are two steps to enable it: allow users to delegate approvals and handle workflow security appropriately. So let's start!
 

Approval Delegation

In order to configure delegation, first of all, we need to configure time period, we want to delegate our approval rights. I suggest adding two Date fields to the UserSettings class of the Membership module: Vacation Start Date and Vacation End Date. Kentico already has appropriate form control - Calendar, which makes date selection much easier and does not require any development efforts. 
Once we can setup our vacation period, we need to have a possibility to specify who will substitute for us. To address this, we need to add one more field: Delegate Approval To and use user selector as a form control for it. This will provide us with possibility to select any user within the system and, again, with no development efforts.
Next step here is to provide users with the UI to setup delegation. Luckily, users, who approve content, should have access to Kentico Administration as well as to My Profile application within it. If you'll check this application, you'll notice, that new fields already appeared there:
 

delegation.jpg
 

So, congratulations - we are done with this. Let's move forward to workflow security.
 

Workflow Security

Doesn't matter if you have approvers configured on the document level, like described in previous post, or using default workflow configuration you'll have to get all the approvers for the current step and check if any of them is on vacation and, if someone is, retrieve user, who substitutes for original approver, and add him to a set of possible/potential approvers. Let's see how code, that handles this, looks like:

 

[assembly: RegisterCustomManager(typeof(CustomWorkflowManager))]
public class CustomWorkflowManager : WorkflowManager
{
    protected override bool CheckStepPermissionsInternal(TreeNode node, UserInfo user, WorkflowActionEnum action)
    {
        if (action == WorkflowActionEnum.Approve)
        {
            // get users allowed to approve from the document
            var approvers = CacheHelper.Cache(cs => GetDocumentApprovers(document, cs), new CacheSettings(60, string.Format("{0}|{1}", "documentapprovers", document.DocumentID)));
            if (approvers.Contains(user))
            {
                return true;
            }  
        }

        return base.CheckStepPermissionsInternal(node, user, action);
    }

    /// <summary>
    /// Retrieves approvers, or their delegates for a given document
    /// </summary>
    /// <param name="document">Document</param>
    /// <param name="cs">Cache settings</param>
    /// <param name="round">Approval round</param>
    /// <returns>Collection of users, who have to approve document</returns>

    private static List<UserInfo> GetDocumentApprovers(TreeNode document, CacheSettings cs)
    {
        var approvers = GetOriginalDocumentApprovers(document); //--> I'm not providing implementation of this method, as it depends on the particular approach         

        var result = GetDelegates(approvers);

        if ((result != null && result.Count > 0) && cs.Cached)
        {
            cs.CacheDependency = CacheHelper.GetCacheDependency("documentid|" + document.DocumentID);
        }

        return result;
    }

    /// <summary>
    /// Substitutes original document approvers in specified list with their delegates
    /// </summary>
    /// <param name="approvers">Original document approvers</param>
    /// <returns>List of actual approvers</returns>
    private static List<UserInfo> GetDelegates(List<UserInfo> approvers)
    {
        List<UserInfo> delegates = new List<UserInfo>();
        //add approvers, those are not on vacation
        delegates.AddRange(approvers.Where(a => !IsUserOnVacation(a)));

        //add approvers, those are not on vacation
        var onVacation = approvers.Where(a => IsUserOnVacation(a));

        foreach (UserInfo user in onVacation)
        {
            int delegateID = user.GetIntegerValue(Constant.USER_DELEGATE_APPROVAL_FIELD_NAME, -1);
            if (delegateID > 0)
            {
                delegates.Add(UserInfoProvider.GetUserInfo(delegateID));
            }
            // no delegate
            else
            {
                delegates.Add(user);
            }
        }

        return delegates;
    }

    /// <summary>
    /// Checks whether given user is currently on vacation
    /// </summary>
    /// <param name="user">User</param>
    /// <returns>Is on vacation</returns>
    private static bool IsUserOnVacation(UserInfo user)
    {
        var vacationStartDate = user.GetDateTimeValue(Constant.USER_VACATION_START_DATE_FIELD_NAME, DateTime.Now.AddHours(-1));
        var vacationEndDate = user.GetDateTimeValue(Constant.USER_VACATION_END_DATE_FIELD_NAME, DateTime.Now.AddHours(-1));
        return (DateTime.Now >= vacationStartDate && DateTime.Now <= vacationEndDate);
    }
}


So this will take care about workflow security and allow delegate to approve a document. However, this does not cover any other permissions, which means, that delegate should have the same level of access as original approver has besides workflow. This includes access to Administration area, Pages application and document(s).
 

Conclusion

We've got a handy tool that allows us to delegate workflow approval with a minimum effort. I'd like to make a point here that whenever you need to extend Kentico default behavior, you have to look for appropriate way or place to do so, like we did with CustomWorkflowManager in this case. No need to jump on Visual Studio and reinvent the wheel and re-develop entire modules. 

Please feel free to leave your feedback or share your experience with similar problems - we highly appreciate this!


Comments
super
Hello!
2/21/2018 1:32:56 AM

cara menggugurkan kandungan
a pride for me to be able to discuss on a quality website because I just learned to make an article on
2/15/2018 6:17:16 AM

cara menggugurkan kandungan
we are happy to comment here, and we await your komantar in our blog
2/15/2018 6:15:47 AM

run 3
In my view this is a useful post and it is very beneficial and well-informed.
2/8/2018 6:18:17 AM

run 3
Your book there is for a generic cover, left, to return, they rely on more expensive.
2/8/2018 6:17:00 AM

cialis
Hello!
2/7/2018 4:47:47 AM

cheap_cialis
Hello!
2/6/2018 12:33:14 PM

cialis
Hello!
1/30/2018 3:23:00 PM

cialis_online
Hello!
1/29/2018 5:27:54 PM

viagra
Hello!
1/23/2018 9:41:30 AM

Dawn Christensen
http://zjfnb.com XvXg6aS3ug, <a href="http://by462.com">ugmeoJEJ</a>, [url=http://iviwj.com]eBZeNqFJ[/url], [csfBhrmdgm0u](http://5fp0r.com "csfBhrmdgm0u"),
1/21/2018 6:05:12 AM

imgrum
Thank you for sharing the post! It's good to see the information.
1/20/2018 9:44:26 AM

purchase_cialis
Hello!
1/19/2018 5:56:16 PM

Samuel Johnson
http://www.adams.biz/ 7pCBNOXN, <a href="http://www.robinson.com/">RiT3XS0DV</a>, [link="http://taylor-stephenson.com/"]70keIpEL01[/link], [url="http://www.kent-knight.com/"]7Zs97QPj[/url], [styI0CDveFW](http://harrison.org/ "styI0CDveFW"),
1/17/2018 7:22:29 PM

cialis_cheap
Hello!
1/16/2018 9:42:44 AM

online_cialis
Hello!
1/12/2018 6:01:06 AM

generic_viagra
Hello!
1/11/2018 4:29:46 PM

buy_cialis
Hello!
1/7/2018 11:56:53 AM

cialis
Hello!
1/4/2018 2:30:22 AM

generic_cialis
Hello!
1/2/2018 11:18:39 AM

cialis
Hello!
12/30/2017 5:37:14 PM

viagra
Hello!
12/27/2017 11:17:34 PM

limousine service westchester
Would anyone be able to make a workflow for an administration organization (any organization). I simply need a thought of how to depict a work process. much appreciated to such an extent!
12/27/2017 1:29:33 PM

Download Jio Tv For Pc
I’m happy I located this blog! From time to time, students want to cognitive the keys of productive literary essays composing. Your first-class knowledge about this good post can become a proper basis for such people. nice one
12/27/2017 10:06:03 AM

buy_viagra
Hello!
12/22/2017 8:42:19 PM

Whitney Wheeler
Wlzy1v49s Ut fugit cupiditate. Repudiandae velit doloribus.
12/12/2017 3:11:25 PM

Capital Gains Tax Advice
I have read your article, it is very informative and helpful for me.I admire the valuable information you offer in your articles. Thanks for posting it..
12/6/2017 3:18:09 PM

Adam Brown
qIsDIV4tELe Rem consequuntur eaque cumque deleniti. Natus lib
12/3/2017 12:47:51 AM

Skrotbilarna
Here I found cheap spare parts for my Volvo, clearly the best yunkyard in Gothenburg. nice and knowledgeable staff
11/18/2017 1:34:00 PM

waqar mazhar
nice post
10/31/2017 4:29:03 PM

paris job
Emploi masseuse naturiste paris Tu aimes te balader et ètre mobile sans ètre coincée dans un lieu voici le job masseuse naturiste paris pour toi, facile sympa relax emploi masseuse naturiste paris.Paris emploi facile pour personne honnète responsible emploi masseuse naturiste paris Tu choisis les lieux de mission contrat indépendent paris emploi Aprends le massage pour le reste de la vie paris emploi masseuse naturiste Job paris mobile sympa relax RDV aller sur.
9/22/2017 6:59:58 PM

Volusion Customization Services
Volusion Customization Services
9/21/2017 11:43:18 AM

bdsm toys
The website is looking bit flashy and it catches the visitors eyes. Design is pretty simple and a good user friendly interface.
9/17/2017 9:16:11 AM

impact of technology on education
The blog is usually very well looked into in addition to facts is usually displayed within a uncomplicated approach. I'd really like to uncover beneficial impact of technology on education in addition to I'm hoping you can guide everyone available to be able. When i have no idea of where to begin in addition to need to have instruction.
5/16/2017 2:57:29 PM

hot sale replica watches
Out of work, party, you may need a watch to reflect your temperament and vision, to show you different from the general taste and vision. Here to meet your needs. thank.
5/5/2017 8:20:16 AM

hot sale replica watches
Out of work, party, you may need a watch to reflect your temperament and vision, to show you different from the general taste and vision. Here to meet your needs. thank.
5/5/2017 2:37:39 AM

computer equipment recycling
Thank you because you have been willing to share information with us. we will always appreciate all you have done here because I know you are very concerned with our.
4/10/2017 3:21:36 PM

Richard
I appreciate you sharing this article.Thanks Again. Really Cool.
3/27/2017 5:40:48 PM

Mark
Hey very nice site!! Man .. Beautiful .. Amazing .. I will bookmark your blog and take the feeds alsoI am happy to find a lot of useful info here in the post, we need work out more techniques in this regard, thanks for sharing. . . . . .
12/9/2016 8:33:08 AM

 Security code