GKK Compressor Industry – Part 2: Production Planning powered by Nintex Workflow

I am going to demonstrate a Production Planning process that is powered by Nintex Workflow in this blog post. Before we get further into the production planning process, let us recap what we have gone through together in my previous sharing in Part 1 of GKK Compressor Industry (i.e. RFQ to Quotation process). In the Sales and Marketing division, Product Catalog is being used to create RFQ, which in turn generates quotations issued to customers. Every quotation issued to customer updates the Sales Forecast with the increased number of compressor model to be delivered.

Being a Lean Manufacturing, Production Planning is crucial to GKK Compressor Industry, the critical success factor is produced only what is needed to be delivered on time. It keeps no unnecessary inventory to minimize the waste of inventory space. Tentative Production Plan is always three months ahead of current month, helps the Procurement to keep the Material Management efficient, knowing what material and quantity of material to order with advance knowledge of the requirement from the production.

Key techniques in the production planning to be shared:

  1. Nintex Form Web Part embedded to the “Draft Production Plan” list/page
  2. “Loop” action alternative for immediate execution
  3. Formatting a monthly calendar with CSR

The Production Plan

The Production Plan is a plan used in the production division with details on what models and quantity of compressor to be produced for a particular month. A production line has its daily production capacity that is dependent on machine and human resource capacity. If a production line can go up to 60 pieces of compressor per calendar day with full capacity running three work shifts, two work shifts will give capacity of 40 pieces.

To get the Actual Production Plan, we draft a production plan from monthly sales forecast with details on what models and quantities to be delivered. The diagram below demonstrates how it’s being created powered by Nintex Workflow. The sample plan shows how the quantity of each model to be produced spread over different days with daily capacity of 30 pieces per day for October 2017. 

To produce a total of 71 pieces of compressor for the first model (i.e. SVT125-35), the work has to be spread into three days, with the third day producing the remaining 11 pieces required to make it 71, since on the third day we produced only 11 pieces for the model, it has the remaining capacity of 19 to produce the next model in line (i.e. SHT277NA in the example).

1. Nintex Form Web Part embedded to the “Draft Production Plan” list/page

I find Nintex Form Web Part very useful especially when I need to make Sharepoint page interactive, but it wasn’t discussed a lot. The Draft Production Plan is just one of the solutions I make use of Nintex Form Web Part to get user to specify or collect Production Plan parameters (i.e. Month, Year, Capacity, and to or not to include week ends as working days for the production plan we are drafting). To include that, I simple embed the “Create Production Plan” workflow’s start form to the “Draft Production Plan” view/page as shown below. Once the form is submitted (i.e. with the Start button in the example), the “Create Production Plan” site workflow will be triggered, and the Draft Production Plan list will be refreshed with the production plan that was drafted by the site workflow.

2. “Loop” action alternative for immediate execution

The algorithm I used for drafting a production plan is summarized as below. I have then realized, it took hours for the workflow to complete a “Production Plan”, reason being the “Loop” action will be executed every 5 minutes by default as it is executed by the Sharepoint Timer Job, even If I configured the Timer Job to run every 1 minute (i.e. minimum interval by Sharepoint), it still take a long time for the workflow to be completed.

  Prepare an empty "Draft Production Plan" view (delete all the existing list items)  Query the "Sales Forecast" for models to be produced for the specified month  For-each models in the list     Create a list item for the model to be produced     Split the total quantity for the model into the number of days required     Loop through each calendar day of the production month            Update the daily quantity for the model to the list item (i.e. exclude/include week end)      End Loop   End For-each‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

We have no choice but to consider to use the “For Each” iteration. Even if you use the State Machine, it is still depending on the Timer Job interval constraint. In order to do that, we will need to calculate the number of loop required, and create a collection of the required number to use the For-each iteration. So, if the quantity to be produced is 71, 71 divide by daily capacity of 30 equals to 2.3667. We get the whole number of 2 leaving behind the fraction, as 2 will be used as collection index of 2 for three iteration (i.e. index starts at 0). This is true if we always start a day with the new daily capacity (e.g. 30), but we will need to consider what if capacity for the day is not always starts from the beginning. In the sample production plan above, the quantity of 22 for model SNT207V is taking 2 days to produce, because the capacity of the day it starts the production was 1 (i.e. 30-29=1) as 29 was used to produce the model prior to it. To get the right count of iteration required, we will need to add the remaining quantity of the last model before we divide the quantity with the capacity, the two calculation actions shown below give the right formula to get the required number of iteration.

3. Formatting a monthly calendar with CSR

From the above Draft Production Plan example, I have customized the “Draft Production Plan” custom list into a calendar look and feel, by coloring the columns representing “week end” into grey. The Custom Side Rendering (i.e. CSR) is a feature by Sharepoint is being used to get the calendar view.

SP.SOD.executeFunc("clienttemplates.js", "SPClientTemplates", function() { 
     SPClientTemplates.TemplateManager.RegisterTemplateOverrides({ 
          OnPostRender: function(ctx) {
               var rows = ctx.ListData.Row;
               var month = rows[0]["Month"];
               var year = rows[0]["Year"];
               var weekends = [];
               var date = new Date(year, month, 0);
               var lastDay = date.getDate();
               for (var d=1;d<=lastDay;d++)
               {
                    date.setDate(d);
                    if (date.getDay()==0 || date.getDay()==6){
                         weekends.push(d);
                    }
               };
               for (var i=0;i<rows.length;i++)
                    {
                         var rowElementId = GenerateIIDForListItem(ctx, rows[i]);
                         var tr = document.getElementById(rowElementId);
                         for (var j=0, len=weekends.length; j<len;j++){
                              var td=tr.cells[weekends[j]+2];
                              td.style.backgroundColor = "#eeeeee";
                         }
                    }
               }
     }); 
});

I have include the script as JSLink shown below