This example shows the creation of a RF form to move quantities of an item from a origin location to a destination location using a task.

The RF form accesses the task, or task list, that shows the item to be moved; using a scanner, the item code, origin location and destination location are captured, the quantity to be moved is entered by the user and finally the stock of the origin location and the status of the processed task is updated. This form must validate each field before moving on to the next one or display an error message.

1 Move stock from one location

The task assigned to the user is to move all or part of the stock of an item from one location to another.

1.1 Analisis

1.1.1 Process flow

The flow that the task will follow is shown below.

1.1.2 Low-level mockup

This is the low level mockup of the form

1.2 Form definition

1.2.1 RF Form

The following section defines the data required for the form.

Field name Content
form_name devtest_ubistk
form_desc Move stock location

JS Client Initial Code: The variable "var_stock" is defined, whose value will be obtained during the execution of the code of the " ubiori " field and will be used in the validation of the " canmov " field by means of "fields.var_stock".

Copy
form.set("var_stock", 0);

For this example it is not necessary to define any code in the "JS Form Server Rollback" section.




1.2.2 Fields

The following section defines the fields required for the form.

field_order field_name field_desc field_title field_type field_noentry field_required
2 codtask Task code Assigned task code S (String) 0 (NO) 1 (YES)
4 destask Task desc. Assigned task description S (String) 1 (YES) 0 (NO)
6 codart Item code Item code S (String) 0 (NO) 1 (YES)
8 nomart Item name Item name S (String) 1 (YES) 0 (NO)
10 ubiori Origin code Origin location code S (String) 0 (NO) 1 (YES)
12 ubides Destiny code Destination location code S (String) 0 (NO) 1 (YES)
14 canmov Quantity Quantity of movement I (Integer) 0 (NO) 1 (YES)

a) The " codtask " field has the following logic:

Server: Obtains the task data. If it exists, display its data in the field " destask " (having a field called " destask ", equal to the property of the object used, the field automatically adopts this value without the need to assign it), otherwise, returns an error message in the variable " errmsg " (returning the object " result " with a property called " errmsg ", automatically creates or updates a variable with this name and value).
Client: Checks if there is any message in the variable " errmsg ", if there is, it displays the message and positions itself in the same field (preventing advancing until a correct value is entered), otherwise, the RF Terminal advances to the next field where data can be entered.

The " mObjTask " object has a property called " codart ", and since there is a field with the same name, this field adopts that value. Therefore, when defining the " result " object, the " codart " property is assigned with an empty value ("") so that when it is returned it does not alter the value of the " codart " field, since it must obtain its value by means of a scanner.

For this example it is not necessary to define any code in the "BEFORE SERVER CODE" section or in "BEFORE CLIENT CODE".

Copy
var result = {
    destask  : "",
    codart   : "",
    errmsg   : ""
};
var mObjTask = Ax.db.executeQuery(`
        SELECT seqno, codart, nomtask
          FROM devtest_gtasku
         WHERE seqno = ?`, fields.codtask).toOne();
if (mObjTask.seqno != null){
    result.destask = "Task >> " +  mObjTask.nomtask + ". Item [" + mObjTask.codart + "]";
} else {
    result.errmsg = "Non-existent task!";
}
return result;
Copy
if (errmsg != "") {
    form.setFocus("codtask", errmsg);
}



b) The " destask " field is descriptive only, so it has no execution code.





c) The " codart " field has the following logic:

Server: Checks if the entered item code exists and also if it corresponds to the task. If the item code corresponds to the task, it returns information in the " codart " and " nomart " fields, otherwise it returns an error message in the " errmsg " variable.

For this example it is not necessary to define any code in the "BEFORE SERVER CODE" section or in "BEFORE CLIENT CODE".

Copy
var result = {
    codart : "",
    nomart : "",
    errmsg : ""
};
var mObjGarticul = Ax.db.executeQuery(`
        SELECT devtest_garticul.codigo, devtest_garticul.nomart
          FROM devtest_gtasku, devtest_garticul
         WHERE devtest_gtasku.codart = devtest_garticul.codigo
           AND devtest_gtasku.seqno  = ? 
           AND devtest_gtasku.codart = ?`, fields.codtask, fields.codart).toOne();
if (mObjGarticul.codigo != null) {
    result.codart = mObjGarticul.codigo;
    result.nomart = mObjGarticul.nomart;
} else {
    result.errmsg = "Item does not exist or does not correspond!";
}
return result;
Copy
if (errmsg != "") {
    form.setFocus("codart", errmsg);
}




d) The " nomart " field is descriptive only, so it has no execution code.





e) The " ubiori " field has the following logic:

Server: Validates the location, obtains the stock in that location and proposes the quantity of movement with this value in the " canmov " field. This same value is stored in the local variable " var_stock ".
Client: Checks if there is any message in the variable " errmsg ", if there is, it displays the message and positions itself in the same field.

For this example it is not necessary to define any code in the "BEFORE SERVER CODE" section or in "BEFORE CLIENT CODE".

Copy
var result = {
    canmov :  0,
    errmsg : ""
};
var mIntGalmstku = Ax.db.executeGet(`
        SELECT stkact
          FROM devtest_galmstku
         WHERE codart = ? 
           AND codubi = ?`, fields.codart, fields.ubiori);
if (mIntGalmstku != null) {
    result.canmov    = mIntGalmstku;
    result.var_stock = mIntGalmstku;//Update the local variable
    result.errmsg    = (mIntGalmstku == 0 ? "Non-existent stock!" : "");
} else {
    result.errmsg = "Location does not exist or does not correspond!";
}
return result;
Copy
if (errmsg != "") {
    form.setFocus("ubiori", errmsg);
}




f) The " ubides " field has the following logic:

Server: Validates that the destination location is different from the origin, and that it exists for a specific warehouse.

For this example it is not necessary to define any code in the "BEFORE SERVER CODE" section or in "BEFORE CLIENT CODE".

Copy
var result = {
    errmsg : ""
};
var mStrUbiori = fields.ubiori,
    mStrUbides = fields.ubides,
    mStrCodalm = "D0001";
if (mStrUbiori != mStrUbides) {
    var mIntCount = Ax.db.executeGet(`
            SELECT COUNT(*)
              FROM devtest_galmubic
             WHERE codigo = ? AND codalm = ?`, mStrUbides, mStrCodalm);
    result.errmsg = (mIntCount == 0 ? "Destination location does not exist!" : "");
} else {
    result.errmsg = `The destination [${mStrUbides}] must be different from the origin [${mStrUbiori}]!`;
}
return result;
Copy
if (errmsg != "") {
    form.setFocus("ubides", errmsg);
}




g) The " canmov " field has the following logic:

Server: Gets the stock value using fields. var_stock and compares it with the quantity to move (" canmov " field). Checks if stock exists in the destiny location, if it does, it increments that stock, otherwise it registers a new stock with the item and destiny location provided. Reduces the origin stock and updates the status of the task. Resets all form fields to start a new task.

For this example it is not necessary to define any code in the "BEFORE SERVER CODE" section or in "BEFORE CLIENT CODE".

Copy
var result = {
    errmsg : ""
};
var mIntCanmov  = fields.canmov,
    mIntStock   = fields.var_stock,
    mStrCodart  = fields.codart,
    mStrUbides  = fields.ubides,
    mStrUbiori  = fields.ubiori,
    mIntCodtask = fields.codtask;
if (mIntCanmov > mIntStock) {
    result.errmsg = `Insufficient stock (Max movement: ${mIntStock})!!`;
} else {
    var mIntStockDest = Ax.db.executeGet(`
            SELECT stkact
              FROM devtest_galmstku
             WHERE codart = ? AND codubi = ?`, mStrCodart, mStrUbides);
    if (mIntStockDest == null) {
        //Item does not exist in the location, an association record will be inserted.
        Ax.db.insert("devtest_galmstku",
            {
                codart : mStrCodart,
                codubi : mStrUbides,
                stkact : mIntCanmov
            }
        );
    } else {
        //Item exists in location, will be added to the existing stock
        Ax.db.update("devtest_galmstku",
            {
                stkact : mIntStockDest + mIntCanmov
            },
            {
                codart : mStrCodart,
                codubi : mStrUbides
            }
        );
    }
    //Reduce stock at origin location
    Ax.db.update("devtest_galmstku",
        {
            stkact : mIntStock - mIntCanmov
        },
        {
            codart : mStrCodart,
            codubi : mStrUbiori
        }
    );
    //Task status update
    Ax.db.update("devtest_gtasku",
        {
            estado : "F"
        },
        {
            seqno : mIntCodtask,
        }
    );
    //Field cleaning
    result.codtask  = "";
    result.destask  = "";
    result.codart   = "";
    result.nomart   = "";
    result.ubiori   = "";
    result.ubides   = "";
    result.canmov   =  0;
}
return result;
Copy
if (errmsg != "") {
    form.setFocus("canmov", errmsg);
} else {
    form.setFocus("codtask", "");
}


1.2.3 Nest form to menu

The created form is nested to a menu, which in this case is TEST_STOCK.

1.3 Soft References

Validates a field using Soft Reference , e.g. for the " codtask " field, displays the task list if the entered task code does not exist or does not correspond to an active task or to the user.

Field name Content
exist_table devtest_gtasku
exist_column seqno
exist_others seqno, codart, nomtask
exist_filters devtest_gtasku.estado='A' AND devtest_gtasku.nomtask='Move location' AND coduser='USER1'

The records returned by Soft Reference are of type String even though the value of " seqno ", for this case, is of type Integer , so the target field " codtask " must also be of type String .

The Soft Reference identifier is recorded in the " field_exist_id " field of " codtask ".




1.4 Process RF

In both cases, starts the execution of the program RF2020 Terminal. In particular, verify that the elements corresponding to config and form have been correctly reported.

Copy
-config login_test
-menu TEST_STOCK

1.4.1 Case 1

Warehouse: D0001
User: USER1

Move 10 pieces of item " 1000002 " from location " 10001 " to location " 10002 "

Initial stock status

DB Studio : Initial stock status.

Copy
SELECT codubi, stkact FROM devtest_galmstku WHERE codart='1000002' AND codubi IN ('10001','10002');
+----+----------+
|codubi| stkact |
+----+----------+
|10001 |    15  |
|10002 |    20  |
+----+----------+

RF Terminal

a) RF Terminal : Access the " devtest_ubistk " form through the menu.



b) RF Terminal (codtask) : Enter the task code, if it does not exist, the list created by SofReference is displayed.

SofReference shows only active tasks.




c) RF Terminal (codart) : Enter the item code. If there is a controlled error, the following message is displayed.

Incorrect value:



Correct value:



d) RF Terminal (ubiori) : Enter the origin location code. If there is a controlled error, the following message is displayed.

Incorrect value:



Correct value:



e) RF Terminal (ubides) : Enter the destination location code. If there is a controlled error, the following message is displayed.

Incorrect value:




Correct value:



f) RF Terminal (canmov) : Enter the quantity to move. If there is a controlled error, the following message is displayed.

Incorrect value:



Correct value:



g) RF Terminal : If the process is successful, the fields are reset.

Success! SoftReference shows only active tasks when entering a value in the " codtask " field.




Final stock status.

DB Studio : Final stock status.

Copy
SELECT codubi, stkact FROM devtest_galmstku WHERE codart='1000002' AND codubi IN ('10001','10002');
+----+----------+
|codubi| stkact |
+----+----------+
|10001 |     5  |
|10002 |    30  |
+----+----------+

1.4.2 Case 2

Warehouse: D0001
User: USER1

Move 8 pieces of item " 1000001 " from location " 10001 " to location " 10005 ".

Initial stock status

DB Studio : Initial stock status.

Copy
SELECT codubi, stkact FROM devtest_galmstku WHERE codart='1000001' AND codubi IN ('10001','10005');
+----+----------+
|codubi| stkact |
+----+----------+
|10001 |    10  |
+----+----------+

RF Terminal

a) RF Terminal : Access the " devtest_ubistk " form through the menu.



b) RF Terminal : Continue with the process




Final stock status.

DB Studio : Final stock status.

Copy
SELECT codubi, stkact FROM devtest_galmstku WHERE codart='1000001' AND codubi IN ('10001','10005');
+----+----------+
|codubi| stkact |
+----+----------+
|10001 |     2  |
|10005 |     8  |
+----+----------+

1.5 After example

Important

If the form created is only an example:

  • Delete the form reference in the menu.
  • Delete form fields
  • Delete the form
  • Delete the SoftReference (if it is related only to the created form).
  • Delete created tables.