Monday, May 29, 2017

List Views based on calculate column containing difference in days between two dates

If you need to find difference in days between two dates suppose "Date 1" & "Date 2" then we use below formula -
=DateDif(Date 1, Date 2,"d") and set return type as Date and Time

But in case you want to set up list view based out of that calculate column we created above then SharePoint will not allow you to do that since return type in above case is Date & Time and it cannot be compared with numerics.

In order to do that, you need to use below formula -
=Date 1 - Date 2 and set return type as number


Now you can set up views based out of this column like if that column value is greater than 60 or less than 100 or any thing like that.

Friday, May 19, 2017

Run SharePoint Workflow on Button Click in List Views using jsLink and JSOM

*This is for SharePoint Online

Sometimes there are requirements from business where they need a button in list view against each item and once you click on it, it should run a workflow for that particular list item.

Make sure to make below changes before using this code.


  •  Change the name of the workflow to start mentioned in variable "WorkflowName",
  •  replace the siteURL
  • Change the column name against which you want to show the button. I am overriding default 'Edit' button 

 /*  Code Starts*/

/*Reference Files*/
<script src="https://siteURL/SiteAssets/jquery-3.2.1.min.js"></script>
<script src="https://siteURL/_layouts/15/SP.Runtime.js"></script>
<script src="https://siteURL/_layouts/15/sp.workflowservices.js"></script>
<script src="https://siteURL/_layouts/15/wfutility.js"></script>
/**/

var itemID = '';
var ItemGUID = '';
var WFSubscriptionID = '';
var WorkflowName = 'Meetings WF';


function getItems(ListTitle, Id) {
    var d = $.Deferred();

    var url = "/_api/web/lists/getByTitle('" + ListTitle + "')/getItemById(" + Id + ")";
    $.ajax({
        url: _spPageContextInfo.webAbsoluteUrl + url,
        type: "GET",
        headers: {
            "accept": "application/json;odata=verbose",
            "content-Type": "application/json;odata=verbose"
        },
        success: function(data) {
            console.log(data)
            d.resolve(data);
        },
        error: function() {
            d.reject('bad request')
        }
    });

    return d.promise();
}


function GetGUID(z, Id) {
    itemID = Id;
    getItems(z, Id).then(function(data) {

        console.log(data.d.GUID);
        ItemGUID = data.d.GUID;
        GetWFSubscriptionID(ctx.listName, itemID, ItemGUID);
    })
}




function StartWorkflowJsLink(overrideCtx) {

    //overrideCtx.listName = "{88E4FF8A-94E8-40AA-89BE-79A98B1CB370}";
    return '<input type="button" value="Start Workflow" onclick="GetGUID(' + "'" + overrideCtx.ListTitle + "'" + ',' + "'" + overrideCtx.CurrentItem.ID + "'" + ')"/>';

}

function registerListRenderer() {

    var overrideCtx = {};


    overrideCtx.Templates = {};

    overrideCtx.Templates.Fields = {

        'Edit': {
            'View': StartWorkflowJsLink
        }

    };


    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
}



ExecuteOrDelayUntilScriptLoaded(registerListRenderer, 'clienttemplates.js');




function GetWFSubscriptionID(ListID, ItemID, ItemGUID) {

    showInProgressDialog();

    var listGuid = "88e4ff8a-94e8-40aa-89be-79a98b1cb370";
    var context = SP.ClientContext.get_current();
    var web = context.get_web();
    var sMgr = new SP.WorkflowServices.WorkflowServicesManager(context, web);
    var sservice = sMgr.getWorkflowSubscriptionService();
    var ssubs = sservice.enumerateSubscriptionsByList(listGuid);
    context.load(ssubs);
    context.executeQueryAsync(
        function() {
            var e = ssubs.getEnumerator();
            while (e.moveNext()) {
                var c = e.get_current();
                if (c.get_name() === WorkflowName) {
                    var subId = c.get_id();
                    WFSubscriptionID = subId;
                    StartWorkflow4(WFSubscriptionID, itemID, ItemGUID);
                }
                //alert("Name :" + c.get_name() + " sID: " + c.get_id());
            };

        },
        function() {

        });




}


var errorMessage = "Something went wrong. To try again, reload the page and then start the workflow.";
var theForm = document.forms['aspnetForm'];
if (!theForm) {
    theForm = document.aspnetForm;
}

function StartWorkflow(iwa) {
    var elIwaStart = document.getElementById("iwaStart");
    elIwaStart.value = iwa;
    theForm.submit();
}
var dlg = null;

function StartWorkflow4(subscriptionId, itemId, itemGuid) {

    var ctx = SP.ClientContext.get_current();
    var wfManager = SP.WorkflowServices.WorkflowServicesManager.newObject(ctx, ctx.get_web());
    var subscription = wfManager.getWorkflowSubscriptionService().getSubscription(subscriptionId);
    ctx.load(subscription, 'PropertyDefinitions');
    ctx.executeQueryAsync(
        function(sender, args) {
            var params = new Object();
            var formData = subscription.get_propertyDefinitions()["FormData"];
            if (formData != null && formData != 'undefined' && formData != "") {
                var assocParams = formData.split(";#");
                for (var i = 0; i < assocParams.length; i++) {
                    params[assocParams[i]] = subscription.get_propertyDefinitions()[assocParams[i]];
                }
            }
            if (itemId) {
                wfManager.getWorkflowInstanceService().startWorkflowOnListItem(subscription, itemId, params);
            } else {
                wfManager.getWorkflowInstanceService().startWorkflow(subscription, params);
            }
            ctx.executeQueryAsync(
                function(sender, args) {
                    closeInProgressDialog();
                    /*var elWf4Start = document.getElementById("wf4Start");
                    elWf4Start.value = 1;
                    theForm.submit();*/
                    window.location.href = window.location.href;
                },
                function(sender, args) {
                    closeInProgressDialog();
                    alert(errorMessage);
                }
            );
        },
        function(sender, args) {
            closeInProgressDialog();
            alert(errorMessage);
        }
    );
}

function closeInProgressDialog() {
    if (dlg != null) {
        dlg.close();
    }
}

function showInProgressDialog() {
    if (dlg == null) {
        dlg = SP.UI.ModalDialog.showWaitScreenWithNoClose("Please wait...", "Waiting for workflow...", null, null);
    }
}

function HandleCheckinBeforeStartWorkflow() {
    var strError = "Please check this document in before starting a workflow.";
    window.alert(strError);
}




/*Code Ends*/

You would be able to see "Start Workflow" button in the overridden column as shown below.


Clicking on the button will run that workflow on the corresponding item.

Wednesday, May 10, 2017

SharePoint Designer Workflow 2013 - Access Denied while Email

Issue :

I had a scenario where we have to send email to a SharePoint Group where initiator does not belong to that group.

While triggering e-mail to that group, workflow threw an error saying

 "Access denied. You do not have permission to perform this action or access this resource".


Resolution 1:

  1.  Go to Site Settings -> Site Permissions
  2. Select Group to which you are sending e-mails.
  3. In group settings, set "Who can view the membership of the group ?" to Everyone

Resolution 2:

  1. Go to Site Settings -> Site Permissions -> Permissions Levels
  2. Open Permission level which is assigned to current user or the group where current user is added.
  3. Make sure, user is having "Create Alerts " permission as shown below.


Tuesday, May 2, 2017

Item level Permission SPD Workflow 2013 Part-3

Workflow Logic

  •  Workflow logic would be 

Action
Status
Item Permission
On Item Submit
Pending with Manager
Created by – Read
Manager - Contribute
Item Approved by Manager
Closed
Created by – Read
Manager – Read
  • As shown in below screen shot. Add App Step to the workflow.
  • When we assign permission on an item, there are 2 steps for that.

  1. Break Role Inheritance: It will stop inheriting permission from parent list and also using Copy Role Assignments =false parameter it will remove all the existing permissions from that item.
  2. Assign Permissions: In the second step we will assign permission to the desired users.


Breaking Role Inheritance

  • Add below steps to the workflow
  • Create a REST URL for breaking role inheritance as shown below

  • Add two headers as shown below.
  • Next step would be to build a dictionary for headers and name it as “Request Headers”. 
  • Accept : application/json;odata=verbose
    Content-Type: application/json;odata=verbose


  • Now Insert call a web service action.
    Select URL that we prepared above.
    Method Type : POST
In the response code, create a variable named responseCode.
             In the Properties section as show below, select Request Headers


  • Now publish the workflow. Create an item in the list and once the workflow execution completes, check the permissions on that item.

Assign Permissions - Pending With Manager



  • Add Steps mentioned above for “Assign Read Permission to Created By”.
  • Set Variable URL as mentioned below.

  • Build Dictionary same as mentioned in previous step and assign it to Request Headers Properties section of call a web service action.
  • Make a Post Call and Publish the workflow.
  • Create another item in the list and check the permission on that item after workflow completes execution.
  • If I check the item level permissions, now Created by user has read permission and Manager has contribute permission

Assign Permission - Approved/Rejected by Manager

  • After above steps, item is now pending with manager for approval.
  • After approval/rejection, we need to set permissions on that item as below.
    • Read for Created by
    • Read for Manager
  • Since Read permission to Created by is already assigned so we do not have to modify anything for that user.
  • Now to assign read permission to Manager, we need to follow below steps.
    • Remove Contribute permission for Manager.
    • Assign read permission for manager.
  • To remove contribute permission for manager and assigning read permission, add actions as below. 

  • For removing manager permission, use below URL and use “DELETE” as the http method




  • For assigning read permission to manager. Add actions as specified in above screenshot highlighted as green.
  • Use below URL and use “POST” as the http method

  • Assign Request Header.
  • Publish the workflow.
  • In the previously created item, edit the same and in Manager Approval select as approved or rejected and click on save.
  • Now check permissions on item