Digiu Digital

SAP Commerce

Enhancing Online Retail Efficiency with SAP Commerce Workflow API

Operational efficiency and customer experience are crucial for success in online retail. For companies looking to streamline their processes and offer a seamless shopping journey, the SAP Commerce Workflow API is a valuable tool. Let’s explore how this solution can transform process management and improve efficiency, helping decision-makers understand its value and implementation.

What is the SAP Commerce Workflow API?

The Workflow API in SAP Commerce Cloud automates complex workflows, from template definition to real-time workflow instance generation. It’s ideal for businesses with regular operations requiring both human interactions and automated tasks, ensuring consistency and efficiency at every step.

Benefits for Decision-Makers

Process Automation

Automation reduces human errors and speeds up operations. The Workflow API allows activities like product price creation and review, web service calls, and validations to be automated, freeing up teams to focus on strategic tasks.

Flexibility and Control

Customizing workflows to meet specific business needs provides unprecedented operational control. Every step, from product creation to marketplace availability, can be precisely orchestrated.

Integration and Scalability

Accessible via Java code or REST/SOAP interfaces, the API integrates easily with other systems. This is crucial for companies seeking scalability and seamless platform integration.

Use Case: Transforming the Shopping Journey

Consider a scenario where product price creation, review, and validation are fully automated. This not only speeds up the time-to-market but also ensures prices are always up-to-date and approved, enhancing customer satisfaction. Let’s see a practical example:

Product Price Creation
Responsible: Creator User
Action: Define the initial product price.

Price Review
Responsible: Approver User
Action: Review and approve the defined price.

Web Service Call
Responsible: Automated System
Action: Send data to an external web service.

Final Validation
Responsible: Workflow Administrator
Action: Validate and finalize the product price.

Implementing the Workflow API

To get started, create workflow templates, define actions and decisions, and finally instantiate and start the workflow. Using Groovy scripts, developers can easily automate and customize these processes.

				
					import de.hybris.platform.workflow.model.WorkflowTemplateModel;
import de.hybris.platform.workflow.model.WorkflowActionTemplateModel;
import de.hybris.platform.workflow.enums.WorkflowActionType;
import de.hybris.platform.workflow.model.WorkflowDecisionTemplateModel;
import de.hybris.platform.workflow.model.AutomatedWorkflowActionTemplateModel;
import de.hybris.platform.workflow.model.WorkflowModel;
import de.hybris.platform.workflow.model.WorkflowItemAttachmentModel;
import de.hybris.platform.core.model.product.ProductModel;
import java.util.Locale;
import java.util.ArrayList;
import java.util.List;
import de.hybris.platform.core.model.ItemModel;
import java.util.Collection;
import java.util.Collections; 

modelService = spring.getBean('modelService');
userService = spring.getBean('userService');
productService = spring.getBean('productService');
catalogVersionService = spring.getBean('catalogVersionService')
workflowService = spring.getBean('workflowService');
workflowTemplateService = spring.getBean('workflowTemplateService');
workflowProcessingService = spring.getBean('workflowProcessingService');
newestWorkflowService = spring.getBean('newestWorkflowService');


workflowTemplateCode = "productPriceWorkflowTemplate";
workflowTemplateName = "product price workflow template";

//action code | action name | action user | action type | jobHandler
ACTION_PLAN = """
        createProductPriceAction|create product price|creatorUser1|START
        createProductPriceReviewAction|create product price review|approverUser1|NORMAL
        makeWebserviceCallForPriceAction|make webservice call for price|workflowAdminUser1|NORMAL|shopzoneAutomatedWorkflowAction
        createProductPriceSignOffAction|create product price sign off|workflowAdminUser1|END
""";


//decision code | decision name | origin action for this decision
DECISION_PLAN = """
        productPriceCompletedDecision|product price completed|createProductPriceAction
        productPriceApprovedDecision|product price approved|createProductPriceReviewAction
        productPriceRejectedDecision|product price rejected|createProductPriceReviewAction
        webservicesCallSuccessDecision|webservice call success|makeWebserviceCallForPriceAction
        webservicesCallFailureDecision|webservice call failure|makeWebserviceCallForPriceAction
""";

//decision code | target next action for this decision
WORKFLOW_LINK = """
        productPriceCompletedDecision|createProductPriceReviewAction
        productPriceApprovedDecision|makeWebserviceCallForPriceAction
        productPriceRejectedDecision|createProductPriceAction
        webservicesCallSuccessDecision|createProductPriceSignOffAction
        webservicesCallFailureDecision|createProductPriceReviewAction
""";

prepareWorkflow(ACTION_PLAN,DECISION_PLAN,WORKFLOW_LINK);

def prepareWorkflow(ACTION_PLAN,DECISION_PLAN,WORKFLOW_LINK)
{
    WorkflowTemplateModel workflowTemplate = createWorkflowTemplate(workflowTemplateCode,workflowTemplateName);
    List<WorkflowActionTemplateModel> workflowActionTemplateList = createWorkflowActions(workflowTemplate, ACTION_PLAN);
    List<WorkflowDecisionTemplateModel> workflowDecisionTemplateList = createWorkflowDecisions(DECISION_PLAN);
    createWorkflowInstance();
}

def createWorkflowTemplate(workflowTemplateCode,workflowTemplateName)
{
    WorkflowTemplateModel workflowTemplate = modelService.create(WorkflowTemplateModel.class);
    workflowTemplate.setOwner(userService.getUserForUID("admin"));
    workflowTemplate.setCode(workflowTemplateCode);
    workflowTemplate.setName(workflowTemplateName, Locale.ENGLISH);
    modelService.save(workflowTemplate);
    return workflowTemplate;
}

def createWorkflowActions(workflowTemplate, ACTION_PLAN)
{
    //action code | action name | action user | action type | jobHandler

    //create list of WorkflowActionTemplateModel
    workflowActionTemplateList = [];

    def actions = ACTION_PLAN.split("\n");

    for (String action : actions) 
    {
        //if action is not blank 
        if(action.isBlank())
        {
            continue;
        }

        def actionDetails = action.split("\\|");
        workflowActionTemplate = null;
        if(actionDetails.length > 4 && actionDetails[4] != null && !actionDetails[4].isBlank())
        {
            workflowActionTemplate = modelService.create(AutomatedWorkflowActionTemplateModel.class);
        }
        else
        {
            workflowActionTemplate = modelService.create(WorkflowActionTemplateModel.class);
        }
        
        workflowActionTemplate.setOwner(userService.getUserForUID("admin"));
        workflowActionTemplate.setCode(actionDetails[0].trim());
        workflowActionTemplate.setName(actionDetails[1], Locale.ENGLISH);
        workflowActionTemplate.setPrincipalAssigned(userService.getUserForUID(actionDetails[2]));
        workflowActionTemplate.setActionType(WorkflowActionType.valueOf(actionDetails[3]));
        workflowActionTemplate.setWorkflow(workflowTemplate);
        //actionDetails[3] is not blanck then set jobHandler
        if(actionDetails.length > 4 && actionDetails[4] != null && !actionDetails[4].isBlank())
        {
            workflowActionTemplate.setJobHandler(actionDetails[4]);
        }
        modelService.save(workflowActionTemplate);
        workflowActionTemplateList.add(workflowActionTemplate);
    }
    return workflowActionTemplateList;
}

def createWorkflowDecisions(DECISION_PLAN)
{
    //decision code | decision name | origin action for this decision

    //create list of WorkflowDecisionTemplateModel
    List<WorkflowDecisionTemplateModel> workflowDecisionTemplateList = new ArrayList<WorkflowDecisionTemplateModel>();

    def decisions = DECISION_PLAN.split("\n");
    for (String decision : decisions) 
    {
        if(decision.isBlank())
        {
            continue;
        }

        def decisionDetails = decision.split("\\|");
        WorkflowDecisionTemplateModel workflowDecisionTemplate = modelService.create(WorkflowDecisionTemplateModel.class);
        workflowDecisionTemplate.setOwner(userService.getUserForUID("admin"));
        workflowDecisionTemplate.setCode(decisionDetails[0].trim());
        workflowDecisionTemplate.setName(decisionDetails[1], Locale.ENGLISH);
        println  decisionDetails[0]+' source action > '+decisionDetails[2];
        workflowDecisionTemplate.setActionTemplate(workflowActionTemplateList.find { it.code == decisionDetails[2] });

        def targetActionModels = findAllTargetActionsForDecision(decisionDetails[0]);

        workflowDecisionTemplate.setToTemplateActions(targetActionModels);
        modelService.save(workflowDecisionTemplate);
        workflowDecisionTemplateList.add(workflowDecisionTemplate);
    }
    return workflowDecisionTemplateList;
}

def findAllTargetActionsForDecision(decisionCode)
{
    //decision code | target next action for this decision

    def links = WORKFLOW_LINK.split("\n");
    def targetActions = new ArrayList<String>();
    for (String link : links) 
    {
        def linkDetails = link.split("\\|");
        if(linkDetails[0] == decisionCode)
        {
            targetActions.add(linkDetails[1]);
        }
    }

    def targetActionModels = [];
    targetActionModels = targetActions.collect { targetAction ->
    WorkflowActionTemplateModel foundModel = workflowActionTemplateList.find { it.getCode() == targetAction }
            if (foundModel == null) {
                throw new RuntimeException("No model found with the code: ${targetAction}")
            }
            return foundModel
    }

   
    targetActionModels.removeAll([null]);
    return targetActionModels;
}


def createWorkflowInstance()
{
    WorkflowTemplateModel workflowTemplate = workflowTemplateService.getWorkflowTemplateForCode(workflowTemplateCode);
                            
    catalog = catalogVersionService.getCatalogVersion('apparelProductCatalog', 'Online');
    ProductModel product = productService.getProduct(catalog,"300618506");

    WorkflowModel workflow = newestWorkflowService.createWorkflow("prodPriceWorkEx1",workflowTemplate, Collections.<ItemModel> singletonList(product),userService.getUserForUID("admin"));
    workflowProcessingService.startWorkflow(workflow);
}
				
			

The SAP Commerce Workflow API is a powerful tool for companies aiming to optimize operations and provide an integrated, efficient shopping experience. By automating complex processes and ensuring consistency at every stage, this solution is essential for business leaders looking to maintain a competitive edge in the digital market.

About Digiu Digital

Digiu Digital specializes in digital transformation and e-commerce, with extensive experience in SAP Customer Experience solutions. We offer 24/7 support and a team of global experts to ensure your business stays ahead.