Scripting
Client
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.
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
import javax.swing.JOptionPane
..
println JOptionPane.showInputDialog("Enter box number")
returns “null” if the cancel button is pressed.
Error dialog
import dk.logiware.shark.system.Dialogs
..
Dialogs.errorDialog("Show the error text here")
Log to the System Log
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.
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.
public void onCreateWindow() {
...
// Start the timer
timer = new Timer(2000, new TimerActionListener());
timer.start();
...
}