|
|
Scripting - Orders
OverviewScripting 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 scriptAs a general rule of thumb – any time you need to automate a process of your business. Consider the following scenarios as an example
Things to know about order scripts
Create and test a scriptCreate new script
Writing a scriptThe 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 1Here 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 Ccase 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. Example 2Imagine 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; 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. 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 scriptTo debug a script you need to create a dummy order and run a script agains 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. F 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 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="[you 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 only the scripting engine will select all paid and unlocked new orders, that did not have the script executed already, and then run the Filter on top of it. Examples of filtersExample 1Consider 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 2Lets 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 3Sometimes 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
For more examples look at the Sample code repository, each example is annotated so it should make sense. |