You are currently viewing documentation for Linnworks Desktop, if you are looking for Linnworks.net documentation, click here.






Scripting - Orders

Videos for this article

Overview

Scripting in Linnworks allows you to inject your own automation behaviour into the system. In another words you can write your own little programs which are executed during the synchronization. The script can amend an order, add new items, send emails, split orders, create Purchase orders automatically and many other things. The script is very much like a macro – an order script will run for every new or processed order on the system and gives you direct access to all properties of an order.

When would you use a script

As a general rule of thumb – any time you need to automate a process of your business. Consider the following scenarios as an example

  • Allocate shipping method to an order based on a set of rules or maybe a cheapest shipping service available for the destination.
  • Recalculate Unites States state tax for an order in a particular way.
  • Add automated notes to an order based on some conditions.
  • Allocate an order to a folder.
  • Allocate an order to a fulfilment center based on a set of conditions
  • Email an order to a drop shipper as a single email.
  • Split an order in a specific way – that is not supported by generic splitting functionality.
  • Add or remote certain items from an order


When a new order is created on the system, Linnworks will run all scripts against the new order. The script may change some properties of an order and save the order – achieving an automation.
A script can also perform other functions, such as automatically send email, create files, communicate with other systems, access web services and many other things.

Things to know about order scripts

  • Script language is C#.  Attached namespaces are:

       System
       System.Data
       System.Xml
       linnworks.finaware.CommonData - linnworks data adapter

  • The script can be configured to run on Open or Processed orders
  • Processed orders – the script will run on orders processed no longer than 10 days ago.
  • Open orders – the script will NOT run on unpaid orders
  • The script will run on an order ONCE. An audit trail record will recorded for the order indicating that the script has been executed. You can force Linnworks to re-run a particular script on all orders, by modifying the script and answering Yes to the Re-Run confirmation prompt.
  • The script DOES NOT save order changes automatically – you must call order.Save(0); to save an order
  • The more scripts you have the slower the sync process is
  • order.Save(0); makes the script slower – only use it when you need to save all the changes in the order
  • If the script takes longer than 5 minutes it will be terminated by timeout cutoff.
  • If the script makes more than 50 data queries to the server – it will be terminated and quarantined. Avoid making unnecessary requests.
  • The more data requests you make – the slower the script – the slower the sync.
  • Since scripting language gives you complete access to all Linnworks data adapters, it is possible to overwrite, create and delete any bit of data in the system – make sure you understand what you are doing and test the implementation.
  • Technical support will be able to give pointers as to how to achieve different things using scripting – but WILL NOT be able to write custom scripts for you unless it is a bespoke development request.
  • There are tonnes of sample scripts – what you need is most likely already written or an existing sample script can be modified to achieve what you need. Explore sample script collection first

Create and test a script

Create new script

  1. Go to Open Order, right click
  2. Configuration > Order Automation
  3. click Add New
  4. Select SCRIPT, then choose whether you want the script to run for new orders or processed orders

  5. Once created double click on the script automation line


Please your code inside Initialize method replacing Your code goes here comment.

Writing a script

The syntax of the code is standard C# with most common namespaces attached in the complilation,  so you have access to file system, networking components etc. But most importantly you have direct access to order object, this is supplied in the Initialize method as a parameter and you can manipulate it from within the code. Since this documentation is not intended to describe every method, field and function in C# and linnworks data adapter, we can only give some pointers as to how to work with scripts. The scripting has full InteliSense – meaning that when you type the code, the method, function or a property of the object will have a comment, which describes what it does.

The syntax editor also checks the syntax as you type, so if you have an incorrect program syntax, the grid at the bottom will display errors.

The syntax might be logically correct, but the script may not compile because of the data type conflicts. Ensure you click Compile to check whether the script can compile.

Best way to explain how to use a script to modify an order is to look at some examples:

Example 1

Here we going to check if an order is from AMAZON and Company name is not empty. If that is the case we going to Upper Case the company name, then save an order. The code inside Initialize method is

 

if (order.Source == "AMAZON" && order.Company != "")
{
    order.Company = order.Company.ToUpper();
    order.Save(0);
}

 

 

So first line we have an IF statement which checks if the loaded order source field is AMAZON and company field is not empty, if this is the case move on to change the company field to company filed in upper case and finally Save order.
Save method of the order object is what actually writes the changes to the database, without it any changes to the order object will not be applied to the database.

Example 2

Imagine you need to itterate through order items and detect if the name of the order item contains a specific word, if there is an item on order with SOME WORD, we need to send an email to the warehouse staff.

 

bool containsSpecialItem = false;
foreach(OrderItem item in order.OrderItems)
{
    if (item.ItemTitle.ToUpper().Contains("SOME WORD")){
        containsSpecialItem = true;
        break;
    }
}
               
if (containsSpecialItem){
    linnworks.finaware.CommonData.Email.SendEmailNow("server", 25, "user", "password", true, "fromemail@email.com", "from name", "toemail@email.com", "to email", "Order " + order.OrderId.ToString() + " need special item", "bla bla bla");
}

 

Lets break down the code into what it does

bool containsSpecialItem = false;

here we simply declaring a boolean variable.

foreach(OrderItem item in order.OrderItems)

itterating through every order item. On each itteration we will get item object of type OrderItem, here we have access to all properties of the order item.

if (item.ItemTitle.ToUpper().Contains("SOME WORD")){

check if the item title contains SOME WORD

containsSpecialItem = true;
break;

set the boolean variable we have declated earlier to true and exit the itterator.

if (containsSpecialItem){

check if the we found an item with SOME WORD

linnworks.finaware.CommonData.Email.SendEmailNow("server", 25, "user", "password", true, "fromemail@email.com", "from name", "toemail@email.com", "to email", "Order " + order.OrderId.ToString() + " need special item", "bla bla bla");

send email to  toemail@email.com

 

This script doesn't make any changes to the order (there is nothing to save), all it does it checks something and can send an email, if necessary.
Note that we have access to SendEmailNow function from linnworks.finaware.CommonData library.
The linnworks.finaware.CommonData is the namespace that contains different data adapters and useful functions. Most of them have comment describing which is available in InteliSense.

For more examples look at the Sample code repository, each example is annotated so it should make sense.

 

Note: Scripts give you virtually unlimited functionality in terms of automation within Linnworks. With this flexibility comes a certain degree of complexity – they can be frustrating little things. If you don't know how to write them and do not wish to learn – get Linnworks tech support to write one for you on bespoke development bases, or ask users on the forum to write one for you, also there are plenty of freelancers who know how to work with these things on freelancer.com

 

 

Debuging a script

To debug a script you need to create a dummy order and run a script agains the order.
Click Run Test and Enter the Order Id of the dummy order. If the script executed successfully, you will see Was/Is window which shows the differences between order before runing a script and after. Here you can see all the changes that were made to the order.

You also have access to debug object. This is useful if you want to output some information from the script to the Was/Is window – which will be displayed at the bottom. 
For example:

debug.AddEntry(order.Country);

will output the shipping country name of the order into the debug window.

Filter – limiting what orders are executed by the script

Filter enables you to run a SQL Query to select a list of unique order ids to limit the orders being executed by the script. This is done in the name of performance as each order script execution takes time – the more complex the script the longer it takes to execute per order, hence limiting number of orders which are evaluated in the first place reduces the load.

Consider a scenario – you want to run a script only for orders in a specific folder and evaluate whether these orders can be moved out of the folder. This can be because you placed them in a folder and waiting for stock to be delivered in order to fulfil the orders. The requirement itself indicates that you have to run the script for all orders in a specific folder only and run the script every time you sync. Since by default Linnworks will run a script for all orders in the open order book this might put a huge strain on the system if you a have lot of orders to deal with. The solution is to limit the script and only execute against order in a specific folder. We can do this by specifying SQL Query that selects a list of order in the specific folder only.

You have to specify a filter as part of the script syntax, in the public string Filter(){} method

Insert the SQL query in the query="[your sql query]"

The query must return one column named pkOrderId – the unique order id

When you are designing the script you click View Filter result to see what orders are being returned as part of the filter.

Note that the filter is executed as part of general select, for example when you running a script for New Orders 
  • The scripting engine for Open Orders will select only orders meeting the following criteria
    • Orders that are Paid 
    • Orders that are Unlocked
    • Orders that have not already had the script executed already
  • Then run the Filter on top of it.

Examples of filters

Example 1

Consider the following scenario. You are running a US State Tax re-calculation for order destined for California. There is no point in running the script for all orders in your order book as you only really want to run the script against order where State is CA. The code inside Filter function will be:

 

string query=@"
SELECT
    pkOrderId
FROM [Order] o
WHERE
    o.bProcessed = 0 AND
    o.nStatus!=0 AND
o.Region ='CA'";
return query;

 

Note that it is a simple SQL statement which only selects pkOrderId. Also note that in order to speed up the filter we also only include bProcessed =0 (only open orders) and nStatus!=0 (paid orders).

Example 2

Lets consider more complex requirement. You have a special folder called Check For Split, and you want to run quite a complex script for orders sitting in this folder only. We also want to run it for orders that have stock level greater than 0, i.e. potential candidates for splitting or moving out of the Check For Split folder.

 

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;

 

Again notice that we making sure we only include unprocessed order (bProcessed =0), paid orders (nStatus=0) and where stock level for one of the products in the order is greater than 1.

Example 3

Sometimes you need to run a script for orders which include only certain order items. For example if you want to run a script for orders that include items that have Extended Property “Run Script” with value Yes. The following filter will apply:

 

string query=@"SELECT
    pkOrderId
FROM [Order] o
INNER JOIN OrderItem oi on oi.fkOrderID = o.pkOrderID
INNER JOIN StockItems sis on sis.pkStockID= oi.fkStockID
INNER JOIN StockItem_ExtendedProperties ext ON ext.fkStockItemId = sis.fkStockControlStockItemId
WHERE
    o.bProcessed = 0 AND
    o.nStatus!=0 AND
    sis.fkStockControlStockItemId IS NOT NULL AND
    ext.ProperyName='Run Script' AND
    ext.ProperyValue='Yes' AND
    ext.ProperyType='Other'";
return query;

 

To design your own filters you will need to understand the database schema of Linnworks. If you are on Linnworks Anywhere, you can install Linnworks Express on a virtual machine or on a computer that doesn’t have Linnworks installed, then install Microsoft Sql Server 2005 Express Management Studio, connect to the local server and explore linnworks_finaware database.

Getting help with scripts and filters


We do have lots of script examples dotted around the forum and documentation - “seek and you shall find”. If you can’t find a solution - post on the forum in Developer’s forum section and we will help you to create a filtering or a script you need.
Unless you are on Enterprise or Professional package we won’t be able to help you in the support tickets with the filters and scripts, in this case post on the forum.


 

For more examples look at the Sample code repository, each example is annotated so it should make sense.



Videos and Files

Order scripting and macro programming in Linnworks - Webinar (1.5h)

The main purpose of the webinar will be to get all new customers familiar with the software by covering basic configuration steps