3

I have a schema with a workflow assigned. I need that if the Performer belongs to a certain group it finishes the process and bypasses the workflow (ending with the Approval Status we have as the latest one: Live). I do this with the Event System (code below).

When I use a user that belongs to the group, then I go to the CMS create a component with a schema that has a workflow, then I click on "Save and Continue" it works and the component ends up in Live Approval status, and it's not in the workflow (if I click "Save" it still in the workflow.

My problem is that if I use Save and Checkin from CoreService from Java code it doesn't work and says item is in workflow. I added logs and when running it from the code it seems it's not entering into the event as it does when doing it from the CMS.

I have already read here but it didn't work. Restarted IIS, all SDL Services and shutdown COM+ too). I put this dll in a separate folder inside bin folder and only 1 time.

Any ideas?

public class WorkflowBypasser : TcmExtension
    {
        static readonly IList<string> WorkflowBypassingGroupNames = LibraryHelper.Helper.GetAppSetting(LibraryHelper.Helper.GetRunningFolder(Assembly.GetExecutingAssembly().CodeBase), "WorkflowBypassingGroupNames").Split(',').ToList();
        static readonly string LiveApprovalStatusTcmUri = LibraryHelper.Helper.GetAppSetting(LibraryHelper.Helper.GetRunningFolder(Assembly.GetExecutingAssembly().CodeBase), "LiveApprovalStatusTcmUri");

        public WorkflowBypasser()
        {
            this.Subscribe();
        }

        private void Subscribe()
        {
            this.EventSystem.Subscribe<Component, CheckInEventArgs>(OnComponentCheckIn, EventPhases.TransactionCommitted);
        }
        #endregion

        private void OnComponentCheckIn(Component component, CheckInEventArgs args, EventPhases phases)
        {
            var xmlElement = component.ToXml();
            var xmlNamespaceManager = new XmlNamespaceManager(new NameTable());
            xmlNamespaceManager.AddNamespace("tcm", "http://www.tridion.com/ContentManager/5.0");

            var activityInstanceNode = xmlElement.SelectSingleNode("//*[local-name()='ActivityInstance']", xmlNamespaceManager);

            if (activityInstanceNode != null)
            {
                try
                {
                    var activityInstanceId = activityInstanceNode.Attributes["xlink:href"].Value;

                    if (!IsValidActivityInstanceId(activityInstanceId))
                    {
                        return;
                    }

                    var activityInstance = new Tridion.ContentManager.Workflow.ActivityInstance(new Tridion.ContentManager.TcmUri(activityInstanceId), component.Session);

                    foreach (var performer in activityInstance.Performers)
                    {
                        foreach (var groupMembership in performer.GroupMemberships)
                        {
                            if (WorkflowBypassingGroupNames.Contains(groupMembership.Group.Title))
                            {
                                ProcessInstance wfProcess = activityInstance.Process.Session.GetObject(activityInstance.Process.Id.ToString()) as ProcessInstance;
                                ApprovalStatus status = new ApprovalStatus(new TcmUri(LiveApprovalStatusTcmUri), activityInstance.Process.Session);
                                var finishedProcess = wfProcess.ForceFinish(status);
                                return;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw new Exception(ex.Message);
                }
            }
        }

        private bool IsValidActivityInstanceId(string activityInstanceId)
        {
            return !activityInstanceId.Equals("tcm:0-0-0");
        }
    }

UPDATE

I few things I noticed

1) If you click Save the workflow remains as Undefined 2) If you click Save checkin event is not fired 3) If you click Save and Close, checkin is fired 4) If you click Save and Close, checkin is fired but if you open the item without refreshing you don't see yet the Live Approval Status the component is in. 5) If you open the component after clicking Save and Close it doesn't show any workflow activity into it, but if you click on the refresh button on the containing folder and then refresh the component window, the workflow can be seen correctly as Live.

So it's like the refresh on the containing folder creates or launches the creation of the workflow activities, but I tried to call Reload on the component, on the OrganizationalItem of the component but none worked.

Java Code

path = componentPath(folder, name);

localizeIfShared(folder, schema, name, path);

sdl.checkOut(path, true, new ReadOptions());

IdentifiableObjectData iod = sdl.read(path, new ReadOptions());

if (iod instanceof ComponentData) {
    if (StringUtils.isNotBlank(data)) ((ComponentData) iod).setContent(data);
    if (StringUtils.isNotBlank(meta)) ((ComponentData) iod).setMetadata(meta);
}

sdl.save(iod, new ReadOptions());
sdl.checkIn(iod.getId(), true, StringUtils.joinIfNotBlank(" : ", "Updated", comment, new Date()), new ReadOptions());
result = SdlObject.asQualified(iod.getId(), SdlObjectType.Component);

UPDATE

As @RickPannekoek mentioned there was no need to call .XML().

This is the final version

var currentActivity = component.CurrentActivity;
if (currentActivity != null)
{
    try
    {
        if (!IsValidActivityInstanceId(currentActivity.Id))
        {
            return;
        }

        foreach (var performer in currentActivity.Performers)
        {
            foreach (var groupMembership in performer.GroupMemberships)
            {
                if (WorkflowBypassingGroupNames.Contains(groupMembership.Group.Title))
                {
                    ProcessInstance wfProcess = currentActivity.Process.Session.GetObject(currentActivity.Process.Id.ToString()) as ProcessInstance;
                    ApprovalStatus status = new ApprovalStatus(new TcmUri(LiveApprovalStatusTcmUri), currentActivity.Process.Session);
                    wfProcess.ForceFinish(status);
                    return;
                }
            }
        }
    }
    catch (Exception ex)
    {
        throw new Exception(ex.Message);
    }
}
5
  • Which version of SDL Web/Tridion are you using? May 20, 2019 at 17:30
  • Any reason for doing component.ToXml() and then obtaining data from the XML representation instead of getting it directly from the Component object? May 20, 2019 at 17:32
  • how does your Java code that calls the Core Service look and what is the exact error (incl. Stack Trace) that you get? May 20, 2019 at 17:53
  • @RickPannekoek SDL 8.5
    – polonskyg
    May 20, 2019 at 18:12
  • @RickPannekoek I've update the question with java code
    – polonskyg
    May 20, 2019 at 18:19

1 Answer 1

0

Finally the fix was to avoid the call to .Save and just call CheckIn.

I didn't know it was being done for existing component and not only new components despite it should happen the same.

Thx!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.