Help Converting Desktop Script To Linnworks.net Script

I found the following Desktop version script which is exactly what I need, but having not a lot of C# experience, I've been racking my brain to try to convert it to the Linworks.net version.  Can anybody help? Basically the script splits an order based on stock availability.


namespace linnworks.finaware.CommonData.Objects                // leave untouched                            
{                                                                                               // leave untouched                           
    public class ScriptMacroClass : linnworks.scripting.core.IOrderScript                       // leave untouched                           
        {                                                                                       // leave untouched                           
            public void Initialize(linnworks.finaware.CommonData.Objects.Order order,linnworks.scripting.core.Debugger debug)           // leave untouched                           
            {                                                                                   // leave untouched                                     
               
                // declare a list of unique ids
                System.Collections.Generic.List<System.Guid> list = new  System.Collections.Generic.List<System.Guid>();       
                               
                // let's collect all order items into a list, so that we can bulk check the stock level for a specific location
                foreach(OrderItem i in order.OrderItems){                                            // iterate through all order items
                    if (i.pkStockItemId != System.Guid.Empty){                                        // is order item linked?
                        list.Add(i.pkStockItemId);                                                    // if yes add to the list
                    }
                }       
 
                // we can get stock levels for a list of items in bulk using the ListCombinedStockAvailablityExcludeOrderFolder method in the inventory
                // we will also exclude all orders in the 'Check For Split' folder from available quantity - This enables us to tell which order items we can take out of the order
                // and move to Ready folder
                List<linnworks.finaware.CommonData.Inventory.StockItemAvailability> availability = linnworks.finaware.CommonData.Inventory.ListCombinedStockAvailablityExcludeOrderFolder(list, "Check For Split", order.GetConnectionString);
               
                debug.AddEntry(availability.Count.ToString());
               
                List<linnworks.finaware.CommonData.Inventory.StockItemAvailability> splitoutItems = new List<linnworks.finaware.CommonData.Inventory.StockItemAvailability>();
                bool allAreAvailable = true;
                foreach(linnworks.finaware.CommonData.Inventory.StockItemAvailability aItem in availability){
                   debug.AddEntry(aItem.SKU + "=" + aItem.Available.ToString());           
                   if (aItem.Available > 0){                                                        // if we have sufficient stock for one of the items
                       splitoutItems.Add(aItem);
                   }else{
                          allAreAvailable=false;
                   }
                  
                   // we now need to check that we have enought to fulfill the whole order line, so count all items on order for this SKU and compare with available
                   int requiredToFulfil = 0;
                   foreach(OrderItem i in order.OrderItems){                                            // itterate through all order items
                       if (i.pkStockItemId ==aItem.pkStockItemId){                                        // is order item linked?
                           requiredToFulfil += i.Qty;
                       }
                   }
                   if (aItem.Available< requiredToFulfil){
                           allAreAvailable=false;
                   }
                  
                }
               
               
               
                // if nothing is available, exit
                if (splitoutItems.Count ==0){return;}
               
                // if all items are available we are just going to put the order in the 'Ready' folder, and log the script as run, so that it never gets re-run
                if (allAreAvailable){
                    order.SetUnassignFromFolder("Check For Split");
                    order.SetAssignToAFolder("Ready");
                    debug.Progress(1,"Reassigning order " + order.OrderId.ToString()+" to Ready");
                    order.Save(0);
                    return;
                }
               
                /*Fun bit - actual splitting out of order items. Here we need to create a list called OrderSplitOutItem to identify which items we want to split out
                  In this particular example we will take out everything we can fulfil.
                  Also this specific example completely ignores composite item children. i.e. it will only split out the parent itself that can be fulfilled
                */
                List<OrderSplitOutItem> splitoutList = new List<OrderSplitOutItem>();
                foreach(linnworks.finaware.CommonData.Inventory.StockItemAvailability availableSKU in splitoutItems){
                   
                    // find order item for the stock item and add it to the split list               
                    foreach(OrderItem i in order.OrderItems)
                    if (i.pkStockItemId == availableSKU.pkStockItemId)
                    {            
                        // here we need to double check that we still have something in stock
                        if (availableSKU.Available>0){
                            // add to splitout list, notice that we check how many we can actually move to split item, if availablity is less than ordered quantity we only move order items we have in stock
                            splitoutList.Add(new OrderSplitOutItem(i.rowid,(i.Qty<=availableSKU.Available ? i.Qty : availableSKU.Available)));
                            availableSKU.Available = availableSKU.Available-(i.Qty<=availableSKU.Available ? i.Qty : availableSKU.Available); // here is a little trick, we reduce local available quantity by number of moved items -
                            //this is to ensure that even if another order item is linked to the same stock item, we will keep available uptodate
                        }
                    }
                }
               
                // double check again that we have something to split
                if (splitoutList.Count==0){return;}
                // add something in the progress
                debug.Progress(1,"Splitting out order " + order.OrderId+". "+splitoutList.Count.ToString() +" items");
               
                //split out the items collected in the splitoutList
                Guid NewOrderId = order.SplitOut(splitoutList,order.fkPostalServiceId,0,"Sufficient stock split");
               
                //save the parent order - THIS IS IMPORTANT - if you split out without saving the parent - you will end up with double orders
                order.Save(0);
                // allocate the new order to a Ready folder
                linnworks.finaware.CommonData.OrderData.AllocateToSingleFolder(order.GetConnectionString,NewOrderId,"Ready");
               
                // mark the order as Macro Running not logged - this will enable Linnworks to rerun the macro for this order on next sync, i.e. The SCRIPT_EXEC audit trail step will NOT be added
                debug.DoNotLogScriptRun = true;
               
                             
            }                                                                                   // leave untouched                           
           
            // the filter is used to limit what order we will feed into the script. this ensures we only check
            // orders that are allocated to Check For Split folder and only the orders that have order items that are available
            public string Filter(){
                string query=@"SELECT o.pkOrderId
FROM [Order] o
INNER JOIN [Order_Folder] oh on oh.fkOrderId = o.pkOrderID AND oh.FolderName='Check For Split'
INNER JOIN [OrderItem] oi on oi.fkOrderID = o.pkOrderID
INNER JOIN [StockItems] sis on sis.pkStockID = oi.fkStockID
INNER JOIN View_CombinedStock s on s.pkstockitemid = sis.fkStockControlStockItemId
WHERE o.bProcessed =0 and o.nStatus!=0 and o.HoldOrCancel=0 and (oi.fkCompositeParentRowId is null or oi.fkCompositeParentRowId=dbo.emptyguid()) AND
    s.[Level]>0
GROUP BY o.pkOrderId";
                return query;
            } 

    }                                                                                           // leave untouched                           
}                                                                                               // leave untouched                         

Login to post a comment