Skip to content

Using Scripting

Client Scripting#

Groovy scripting is supported for some of the SHARK Windows. This allows for modifications to the layout and display as well as changing or adding to the functionality. The script works as an extension to the existing Java code and can make use of general resources to the SHARK client. To make script extensions, you should have knowledge about the following technologies:

  • Groovy and Java
  • Swing to implement graphical extensions.
  • The API interfaces to SHARK.

How to Edit Scripts#

The scripts are stored in the database. There is a build-in script editor, that can be reached from the configuration menu in the related window or from a common Script Editor found under the Files menu.

Goods Reception#

Panel Layout#

The panel layout can be used to place new graphical elements in the window.

Extension Class#

Order Pick and Put (Floating Batch Pick)#

The Batch Picking Window can be customized by scripting.

To create the script:

Open the configuration window

Enable scripting and open the editor

Edit and save the script

The script can now be edited. The first time a default script will be assigned.

When the OK button is pressed the script will be saved and reloaded, it is not necessary to close the batch order window to make the changes to take effect. If there are compilation errors, they will show up and must be fixed.

package dk.logiware.shark.transactions.floatingbatchpick;

import dk.logiware.shark.model.FloatingBatchPickVO
import dk.logiware.shark.transactions.floatingbatchpick.TransactionsHandlingWindow
import dk.logiware.shark.transactions.floatingbatchpick.TransactionsHandlingController
import dk.logiware.shark.transactions.floatingbatchpick.TransactionsHandlingWindowExtensionIF
import dk.logiware.shark.guicomponents.DialogHandlerBase
import dk.logiware.shark.scripting.PanelScriptExtension         
import dk.logiware.shark.transactions.floatingbatchpick.QuickOrderDialog          
import dk.logiware.shark.SharkSystem;
import dk.logiware.shark.guicomponents.DialogHandlerDialog;
import dk.logiware.shark.guicomponents.SHARKDialog;
import dk.logiware.shark.guicomponents.SHARKDialog2;
import dk.logiware.shark.guicomponents.SHARKDialogHandler;
import dk.logiware.shark.guicomponents.SHARKPanelIf;
import dk.logiware.shark.guicomponents.SHARKTablePanel;
import dk.logiware.shark.model.GoodsReceptionHandler;
import dk.logiware.shark.transactions.manualorders.ManualOrderHandler                                                                
import dk.logiware.shark.model.ItemVO
import dk.logiware.shark.model.OrderVO      
import dk.logiware.shark.model.TransactionsHandlingHandler         
import  dk.logiware.shark.model.OrderReleaseHandler

/**
 *
**/
public class TransactionsHandlingWindowExtension implements TransactionsHandlingWindowExtensionIF {
    TransactionsHandlingWindow transactionsHandlingWindow
    TransactionsHandlingControllerIf controller

    /**
     * Called when the Transaction handling window is opened.
     * 
     * @param transactionHandlingWindow "this" pointer to the TransactionHandlingWindow.
     * 
     */
     @Override
    public void init(TransactionsHandlingWindow transactionHandlingWindow) {
        this.transactionsHandlingWindow = transactionHandlingWindow
        controller = transactionHandlingWindow.getController()
    }   


    /**
     * Called before a new transaction is displayed.
     * 
     * @param transaction
     */
     @Override
    public void onBeforeDisplayTransaction(FloatingBatchPickVO transaction) {
    }


    /**
     * Called when a new transaction is displayed.
     * 
     * @param transaction
     */
     @Override
    public void onAfterDisplayTransaction(FloatingBatchPickVO transaction) {
    }


    /**
     * Called when text is entered into the scan field. 
     * Works as a filter, returns the text unmodified unless modifications 
     * are required to the entered text.
     * 
     * @param text
     * @return
     */
     @Override
    public String onTextEntered(String text) {             
        return text
    }


    /**
     * Called when a location in the tray view is clicked.
     * 
     * @param location The location in the Tray View (eg. A1 or C4)
     */
     @Override
    public void onTrayViewClicked(String location) {}

    /**
     * Called just before the transaction is confirmed.
     */
     @Override
    public void onConfirmTransaction(FloatingBatchPickVO transaction)  {;}

    /**
     * Called when the order is completed.
     * 
     * @param transaction
     */             
     @Override
     public void onOrderDone(FloatingBatchPickVO transaction)  {;}              

     public void onCreate(DialogHandlerBase content) {;}
     public void onCreateWindow(){;}
     public void onOpen() {;}
     public void onClose() {;}
     public void onCloseWindow() {;}
     public void onDestroy() {;}
} 

Examples#

Here are some usefull examples of what is possible.

Create an order from a barcode#

This can be used to create for example a Kanban order from a barcode that contains article number and quantity.

    /**
     * Called when text is entered into the scan field. 
     * Works as a filter, returns the text unmodified unless modifications 
     * are required to the entered text.
     * 
     * @param text
     * @return
     */
     @Override
    public String onTextEntered(String text) {             

        if (text.startsWith('KAN')) {
           def body = text.substring(3)
           def tokens = body.split('#'
           def article = tokens[0]
           def qty = Double.parseDouble(tokens[1])

           println "Scanned kanban label for $article qty=$qty"

           // Get the ItemID for the scanned article             
           ItemVO[] voItems = ManualOrderHandler.findItem(article, null)

           // Create an order for this article. The order type is 105 and it has AutoRelease enabled
           OrderVO voOrder = ManualOrderHandler.newOrder(null, 105, false, null, null);
           ManualOrderHandler.newOrderline(voOrder, voItems[0], null, qty);
           ManualOrderHandler.orderReady(voOrder);

           // Activate the just created order
           TransactionsHandlingHandler.setWorkingOrder(voOrder.getID(), true);
           TransactionsHandlingHandler.startPick(voOrder.getID());

           // To make a dispatch - forces the client to read orders up from the database
           controller.ordersDeleted()

           // The client should not react to this input
           text = 'IGNORE'

        }
        return text
    }
Remove confirmation check for some picks#

This snippet will allow simple confirmation for orders that do not have a box assigned to the order. This could be if most orders are picked by a pick cart with boxes and with confirmation done by pressing a pick-by-light key, but a few orders are picked with a simple activation of a single order.

    public void onAfterDisplayTransaction(FloatingBatchPickVO transaction) {        
       // If the transaction has no box number, simple accept mode is enabled
       if (transaction.getBoxNumber() == '') {                                
        println "Disable box confirmation"
        controller.transactionValidator.setDone(0)
       }
    }

To make it work, the parameter below must also be set:

Add a new button with an action to the Action Menu#

Add a new button to the Action menu at the lower right corner of the screen and perform some action when the button is pressed.

    public void onCreateWindow() {          
        Runnable myAction = new Runnable() {
            @Override
            public void run() {
                println "MY Action is pressed"
            }
        };

        transactionsHandlingWindow.addButton('MY ACTION', myAction)  
    }

Manual Transactions#

package dk.logiware.shark.transactions.manualtransactions;

public class ManualTransactionScriptExtension implements ManualTransactionScriptExtensionIF {

    private  ManualTransactionsView view

    public void onCreate(ManualTransactionsView manualTransactionsView) {
       view = manualTransactionsView}

    public void onCreateWindow() {}

    public void onOpen() {}

    public void onClose() {}

    public void onCloseWindow() {}

    public void onDestroy() {}

    public String onArticleEnter(String text) {
        return text
    }

    public String onLocationEnter(String text) {
    return text
  }    

    public boolean onNewLocation() {

  }                                         

    public boolean onAction() {

  }
}

Fields#

Field Set  Get Notes
Article Number  view.txtItemNumber.setText(..) view.txtItemNumber.getText(..)
Article Description  view.txtItemName.setText(..) view.txtItemName.getText(..)
Location view.txtLocation.setText(..) view.txtLocation.getText(..)
Qty view.txtQty.setText(..) view.txtQty.getText(..)
Scanning of article numbers#

The default behaviour of the enter key in the article field is to search for information in both article number and description field. This may conflict with a possible scanning of article numbers with old content in the description field.

The following code will prevent this by clearing the article name field before the search :

    public String onArticleEnter(String text) {
       view.txtItemName.setText("") 
       return text
    }

Initialization Script#

When the client application start, it is possible to execute a script. The script must be named "SharkAppInit".

Examples of init scripts:

Rename the PC to something else#

import dk.logiware.shark.SharkSystem
import dk.logiware.shark.system.Globals


public class SharkAppExtension extends SharkAppExtensionBase    {  

    @Override
    public void init() {
        SharkSystem.setPCNameCommandline("DemoPC1")
        Globals.reconnectDispatcher()
    }
}

Add a new menu entry#

Example of adding a new menu entry with an action that will be executed when the menu is selected.

Script code
import dk.logiware.shark.SharkSystem
import dk.logiware.shark.SystemMenu
import dk.logiware.shark.ActionHandler
import dk.logiware.shark.ActionHandler.Listener 
import dk.logiware.shark.constants.*
import javax.swing.AbstractAction
import java.awt.event.ActionEvent
import java.util.Enumeration;
import dk.logiware.shark.scripting.SharkAppExtensionBase

public class SharkAppExtension extends SharkAppExtensionBase    {  

    class MyAction extends AbstractAction {
        public void actionPerformed(ActionEvent e) {
            println "Hello"
        }
    }

    @Override
    public void init() {
        ActionHandler.getInstance().actions.put('MyAction', new MyAction());
        SharkSystem.getSystemMenu().addMenuItem(MenuConstants.FILE_MENU, 'Say Hello', 'MyAction', null)
    }

}

Code Snippets#

Here is some code examples of useful common tasks.

Prompt for input#

Script code
import javax.swing.JOptionPane
..
println JOptionPane.showInputDialog("Enter box number")

returns "null" if the cancel button is pressed.

Error Dialog#

Script code
import dk.logiware.shark.system.Dialogs
..
Dialogs.errorDialog("Show the error text here")

Log to the System Log#

Script code
import dk.logiware.shark.SharkSystem
..
def severity = 1 // 0:Error 1:Warning 2:Info 3:Detailed
def errorcode = 9999
def message = 'Short error message'
def orderNumber = 'Order number field'
def details = 'Detailed description of the logging'
SharkSystem.errorLog(severity, errorcode, message, orderNumber, details)

Timer Function#

Sometime is can be usefull to have an action executed at fixed intervals automatically. This can be implemented by a timer.

Note that some of the scripting places, already have a timer available.

Add a timer variable and define the action listener at the top of the script class.

Script code
import import javax.swing.*; 
...
public class TransactionsHandlingWindowExtension extends TransactionsHandlingWindowExtensionAbstract {
    ...
    Timer timer;    

    class TimerActionListener implements ActionListener {
      public void actionPerformed(ActionEvent e) {   
          println "Timer action executed"
      }
    }
    ...

Then start the timer, for example when the window is created. This one will run every 2 seconds.

Script code
public void onCreateWindow() {          
    ...
    // Start the timer
    timer = new Timer(2000, new TimerActionListener());   
    timer.start();  
    ...          
}

Call a Stored Procedure in the Database#

The script has no direct access to the database, but it might call stored procedures which has been defined in the database with the right permissions.

Script code
// Import packages
import dk.logiware.rpchandler.RPCCall;
import dk.logiware.rpchandler.RPCMethod;
import dk.logiware.rpchandler.RPCUtil;
...
// Call the stored procedure (here SharkLink_NewArticle) with parameters
RPCCall sc = RPCUtil.createRPCCall();
RPCMethod sm = sc.createRPCMethod("SharkLink_NewArticle");
sm.createRPCParameter("AlternativeItemNumber1").setValue(tokens[7]);
sm.createRPCParameter("Description1").setValue(tokens[6]);
sm.createRPCParameter("ItemName").setValue(tokens[2].trim());
sm.createRPCParameter("ItemNumber").setValue(tokens[1].trim());
sc.execute()