WarehousePro Documentation

Custom Detail screens

WarehousePro includes (as of version 3.1.3.0) the possibility to present additional information about documents or rules via custom / freely configurable detail screens.

For this, a "query" can be written per task type to retrieve the desired data. Each task type has a specific range of "input parameters" with which this query can be executed.

This document explains how this functionality works and some examples will be given that can be used on SQL and / or HANA environments. This document does not contain a detailed explanation of the possibilities on these database platforms.

Settings

The settings for determining the data can be found via the menu path Administration > Setup > WarehousePro Settings > Configuration > Details Definitions.

If no definition is defined in this screen for a specific task, an internal standard is used in which fixed fields are used to display fixed information.

Even when an error is recognized in the query during its execution, WarehousePro will automatically fall back on the fixed information.

Details Definitions

When a Detail screen needs to be adjusted, the relevant function can be added via the New button at the bottom of the screen.

A new "moment" appears where two tabs can be filled: "Show automatically" and "Script". A SQL script is expected in both tabs. The SQL syntax must correspond to the database platform on which the SAP Business One administration is located.

image3.png

In both cases, the same input parameters are available to base a query. They do not all have to be used. The parameter (place holder) is replaced when the query will be executed. For each parameter, additional information is shown about how it will be filled. Hereby a short explanation about the parameters from the screen print above.

@UserID

Based on the additional explanation "APD_TERMINAL_USERS.User_ID" we can conclude that the parameter 1 contains a value and that more information can be found and retrieved in the table "APD_TERMINAL_USERS".

@Language

This parameter returns the language code of the current session. This could be used to display information in the relevant language to the user.

@Documents

This parameter has a somewhat more complex structure. The (,) indication in the explanation indicates that multiple values can be available in the parameter. This can occur, for example, when multiple purchase orders are being received together. The data in the parameter is separated by a comma. In addition, the value consists of the data BaseType and DocEntry (this time separated by the “-” sign. An example: 22-20012,22-20089. In order to be able to use the data from both documents, this parameter must first be parsed in the custom query before this is possible. Sample queries are available in this document.

Automatically show

It is important to bear in mind that the query in the "Auto Show" tab may only return a single value "Y" (for yes, automatically show) or "N" (for no, do not automatically show).

Script

It is important to bear in mind that the query in the "Script" tab may return a maximum of one value. If multiple data is to be displayed, this will have to be collected in one text field. So first convert all data to text before merging it with other data. A few examples are given below.

Examples

In these examples, the detail screen is automatically displayed when the item number is “A00001”.

The detail screen itself is filled with the information that is built up in variable "Result". The screen displays item code, description and the "free text" field of all relevant document lines.

image4.png
MSSQL Orderpicking Line

This example uses 1 stored procedure "WHP_CUSTOM_DETAILS_ORDER_PICKING_LINE". Here both the automatic display and the script are determined. Via the input parameter "@Trigger" it is indicated which query should be executed.

Stored Procedure:

CREATE PROCEDURE WHP_CUSTOM_DETAILS_ORDER_PICKING_LINE (@Trigger NVARCHAR(1), @AbsEntry INT, @PickEntrys NVARCHAR(2000))
AS
BEGIN
        DECLARE @PickEntryTable TABLE(PickEntry INT)

        INSERT INTO @PickEntryTable
        SELECT CAST(value AS INT) FROM STRING_SPLIT(@PickEntrys, ',')

        IF @Trigger = 'Y'
        BEGIN
                    --Trigger

                    SELECT CASE WHEN A.ItemCode = 'A00001' THEN 'Y' ELSE 'N' END FROM
                    (
                           SELECT DISTINCT L.ItemCode
                           FROM APD_OPKL_1 T WITH(NOLOCK)
                           INNER JOIN (
                                    SELECT 17 AS BaseType, R.DocEntry, R.LineNum, R.ItemCode FROM RDR1 R WITH(NOLOCK)
                                    UNION
                                    SELECT 13 AS BaseType, I.DocEntry, I.LineNum, I.ItemCode FROM INV1 I WITH(NOLOCK)
                           ) L ON T.BaseObject = L.BaseType AND T.OrderEntry = L.DocEntry AND T.OrderLine = L.LineNum
                           WHERE T.AbsEntry = @AbsEntry AND T.PickEntry IN (SELECT * FROM @PickEntryTable)
                    ) A
        END
        ELSE
        BEGIN
                    --Script

                    DECLARE @Data TABLE(ItemCode NVARCHAR(100), ItemName NVARCHAR(100), Comment NVARCHAR(MAX))

                    INSERT INTO @Data
                    SELECT L.ItemCode, L.Dscription, L.Comment
                    FROM APD_OPKL_1 T WITH(NOLOCK)
                    INNER JOIN (

                        SELECT 17 AS BaseType, R.DocEntry, R.LineNum, R.ItemCode, R.Dscription, ISNULL(R.FreeTxt,'') AS Comment FROM RDR1 R 
                        WITH(NOLOCK)

                        UNION

                        SELECT 13 AS BaseType, I.DocEntry, I.LineNum, I.ItemCode, I.Dscription, ISNULL(I.FreeTxt,'') AS Comment FROM INV1 I 
                        WITH(NOLOCK)
                    ) L ON T.BaseObject = L.BaseType AND T.OrderEntry = L.DocEntry AND T.OrderLine = L.LineNum
                    WHERE T.AbsEntry = @AbsEntry AND T.PickEntry IN (SELECT * FROM @PickEntryTable)

        DECLARE @CommentData TABLE(ID INT IDENTITY, Comment NVARCHAR(MAX))
        DECLARE @CommentID INT = 1

        INSERT INTO @CommentData (Comment)
        SELECT T.Comment FROM @Data T WHERE T.Comment != ''

        DECLARE @Result NVARCHAR(MAX)

        SET @Result = 'Artikel = ' + (SELECT TOP(1) T.ItemCode FROM @Data T) + CHAR(10)
        SET @Result = @Result + 'Omschrijving = ' + (SELECT TOP(1) T.ItemName FROM @Data T) + CHAR(10) + CHAR(10)
        SET @Result = @Result + 'Commentaar' + + CHAR(10) + CHAR(10)

        WHILE @CommentID <= (SELECT MAX(D.ID) FROM @CommentData D)
        BEGIN
                    SET @Result = @Result + (SELECT T.Comment FROM @CommentData T WHERE T.ID = @CommentID) + CHAR(10)
                    SET @CommentID = @CommentID + 1;
        END;

        SELECT @Result

    END

END

In this example, the input parameter "@PickEntrys" is first loaded into a temporary table. This is done via the following code:

INSERT INTO @PickEntryTable
SELECT CAST(value AS INT) FROM STRING_SPLIT(@PickEntrys, ',')

By storing the following queries in the Detail Definitions (after saving this stored procedure in the SAP database), this logic can be applied:

Automatically show:

EXECUTE WHP_CUSTOM_DETAILS_ORDER_PICKING_LINE 'Y', @AbsEntry, @PickEntrys

Script:

EXECUTE WHP_CUSTOM_DETAILS_ORDER_PICKING_LINE 'N', @AbsEntry, @PickEntrys
MSSQL String Split for older SQL Server versions

Some MS SQL Server versions do not hot have a built in String_Split function. In this case you could use the following function which will add the same function to these SQL

Server versions:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE FUNCTION STRING_SPLIT
(
    @INPUT_STRING NVARCHAR(MAX),    
    @DELIMITER NVARCHAR(1)
)

RETURNS @SPLIT_VALUES TABLE(VALUE NVARCHAR(1000))

AS
BEGIN

    DECLARE @SPLIT_PART NVARCHAR(MAX) = '';
    DECLARE @POS INT

    WHILE CHARINDEX(',', @INPUT_STRING) > 0

    BEGIN

        SELECT @POS = CHARINDEX(',', @INPUT_STRING)
        SELECT @SPLIT_PART = SUBSTRING(@INPUT_STRING, 1, @POS-1)

        INSERT INTO @SPLIT_VALUES

        SELECT @SPLIT_PART
        SELECT @INPUT_STRING = SUBSTRING(@INPUT_STRING, @POS+1, LEN(@INPUT_STRING)-@POS)

    END

        IF @INPUT_STRING != ''
    
        BEGIN

            INSERT INTO @SPLIT_VALUES
            SELECT @INPUT_STRING

        END

    RETURN

END

GO
SAP HANA Orderpicking Line

This example uses a stored procedure and a function to parse the input parameter of different documents.

CREATE PROCEDURE "SCHEMA"."WHP_CUSTOM_DETAILS_ORDER_PICKING_LINE" (IN Trigger NVARCHAR(1), IN AbsEntry INT, IN PickEntrys NVARCHAR(2000)
LANGUAGE SQLSCRIPT AS
BEGIN
    DECLARE Result NVARCHAR(6000) := '';
    DECLARE CommentID INT := 1;
    DECLARE MaxCommentID INT := 0;
    DECLARE ItemCode NVARCHAR(150) := '';
    DECLARE ItemName NVARCHAR(150) := '';
    DECLARE Remarks NVARCHAR(400) := '';

    CREATE LOCAL TEMPORARY TABLE #PickEntryTable ("PickEntry" INT);
    CREATE LOCAL TEMPORARY TABLE #Data ("ItemCode" NVARCHAR(100), "ItemName" NVARCHAR(100), "Comment" NVARCHAR(4000));
    CREATE LOCAL TEMPORARY TABLE #CommentData ("ID" INT, "Comment" NVARCHAR(4000));
    
    INSERT INTO #PickEntryTable
    SELECT CAST("OUTPUT_SPLIT" AS INT) FROM "SCHEMA"."STRING_SPLIT"(:PickEntrys, ',');

    IF :Trigger = 'Y' THEN
            --Trigger
    
            SELECT CASE WHEN A."ItemCode" = 'A00001' THEN 'Y' ELSE 'N' END AS Result FROM
            (
                    SELECT DISTINCT L."ItemCode"
                    FROM "SCHEMA"."APD_OPKL_1" T
                    INNER JOIN (
                        SELECT 17 AS "BaseType", R."DocEntry", R."LineNum", R."ItemCode" FROM "SCHEMA"."RDR1" R
                        UNION
                        SELECT 13 AS "BaseType", I."DocEntry", I."LineNum", I."ItemCode" FROM "SCHEMA"."INV1" I
                    ) L ON T."BaseObject" = L."BaseType" AND T."OrderEntry" = L."DocEntry" AND T."OrderLine" = L."LineNum"
                    WHERE T."AbsEntry" = :AbsEntry AND T."PickEntry" IN (SELECT * FROM #PickEntryTable)
            ) A;
    ELSE
            --Script

            INSERT INTO #Data
            SELECT L."ItemCode", L."Dscription", L."Comment"
            FROM "SCHEMA"."APD_OPKL_1" T
            INNER JOIN (
                    SELECT 17 AS "BaseType", R."DocEntry", R."LineNum", R."ItemCode", R."Dscription", IFNULL(R."FreeTxt",'') AS "Comment" FROM "SCHEMA"."RDR1" R
                    UNION
                    SELECT 13 AS "BaseType", I."DocEntry", I."LineNum", I."ItemCode", I."Dscription", IFNULL(I."FreeTxt",'') AS "Comment" FROM "SCHEMA"."INV1" I
            ) L ON T."BaseObject" = L."BaseType" AND T."OrderEntry" = L."DocEntry" AND T."OrderLine" = L."LineNum"
            WHERE T."AbsEntry" = :AbsEntry AND T."PickEntry" IN (SELECT * FROM #PickEntryTable);

            INSERT INTO #CommentData
            SELECT ROW_NUMBER() OVER (ORDER BY T."Comment"), T."Comment" FROM #Data T WHERE T."Comment" != '';
            
            SELECT MAX(D."ID") INTO MaxCommentID FROM #CommentData D;
            SELECT TOP 1 T."ItemCode" INTO ItemCode FROM #Data T;
            SELECT TOP 1 T."ItemName" INTO ItemName FROM #Data T;

            Result := 'Artikel = ' || :ItemCode || CHAR(10);
            Result := :Result || 'Omschrijving = ' || :ItemName || CHAR(10) || CHAR(10);
            Result := :Result || 'Commentaar' || CHAR(10) || CHAR(10);

            WHILE :CommentID <= :MaxCommentID
            DO
                        SELECT T."Comment" INTO Remarks FROM #CommentData T WHERE T."ID" = :CommentID;
                        
                        Result := :Result || :Remarks || CHAR(10);
                        CommentID := :CommentID + 1;
            END WHILE;
            
            SELECT :Result AS Result FROM DUMMY;

    END IF;

    DROP TABLE #CommentData;
    DROP TABLE #Data;
    DROP TABLE #PickEntryTable;

END;
Multisplit (MSSQL and SAP HANA)

When a variable (such as "@Documents" as an example in this document) contains multiple data, a multi-split function is required.

Here are examples for MSSQL and SAP HANA.

MSSQL:

DECLARE @CombiData NVARCHAR(MAX) = '17-1-1,17-1-2,13-3-4,13-4-1'

DECLARE @Documents TABLE(BaseType INT, DocEntry INT, LineNum INT)

INSERT INTO @Documents
SELECT PARSENAME(REPLACE(value,'-','.'),3) as BaseType,
       PARSENAME(REPLACE(value,'-','.'),2) as DocEntry,
       PARSENAME(REPLACE(value,'-','.'),1) as LineNum
FROM STRING_SPLIT(@CombiData, ',')

SELECT * FROM @Documents

SAP HANA Multisplit

CREATE PROCEDURE WHP_EXAMPLE_MULTI_SPLIT (IN DocumentLines NVARCHAR(2000))
LANGUAGE SQLSCRIPT AS
BEGIN
    
        CREATE LOCAL TEMPORARY TABLE #EntryTable ("BaseType" INT, "DocEntry" INT, "LineNum" INT);

        INSERT INTO #EntryTable
        SELECT CAST(SUBSTRING_REGEXPR('[^-]+' IN "OUTPUT_SPLIT" FROM 1 OCCURRENCE 1) AS INT) AS "BaseType",
               CAST(SUBSTRING_REGEXPR('[^-]+' IN "OUTPUT_SPLIT" FROM 1 OCCURRENCE 2) AS INT) AS "DocEntry",
               CAST(SUBSTRING_REGEXPR('[^-]+' IN "OUTPUT_SPLIT" FROM 1 OCCURRENCE 3) AS INT) AS "LineNum"
        FROM STRING_SPLIT(:DocumentLines, ',');

        SELECT * FROM #EntryTable;

        DROP TABLE #EntryTable;
END;