1 Context:
For this task we will use the Screen “TrainingDay5_OrderOverview” and enhance the Form that is used in that Screen.
2 Step by step guide:
2.1 Implement a logic parameter
First we will implement our Backend Business-Logic
- 👋In your ProCode Workspace create a new File in “/src/backend/BusinessLogic” -> and name it “OrderInfoParameter_<myName>.cls”
- 💡This will become the Parameter for the Logic we are going to implement.
- 👋 Start typing “b1-logicParameter” and select the template
- 💡 This will create a parameter-class for you with 3 sample Attributes. For our OrderInfo Business-Logic we want to receive a customer-number, and return the number of orders for that customer, as well as a message if there is any error. After defining those 3 Attributes our Parameter-Object will look like this:
BLOCK-LEVEL ON ERROR UNDO, THROW.
CLASS <yourFileName>
INHERITS Consultingwerk.JsonSerializable:
/* Input properties */
{ Akioma/Swat/JsonSerializableProperty.i custNum integer }.
/* Output properties */
{ Akioma/Swat/JsonSerializableProperty.i numOrders integer }.
{ Akioma/Swat/JsonSerializableProperty.i Message CHARACTER }.
CONSTRUCTOR PUBLIC <yourFileName>():
SUPER().
THIS-OBJECT:AddSerializableProperties("{&SerializableProperties}").
END CONSTRUCTOR.
END CLASS.
- 👋Save the file.
- 💡 A corresponding .r file will be automatically created.
2.2 Implement the Business Logic
- 👋 Create another File in “/src/backend/BusinessLogic” -> and name it “OrderLogic_<myName>.cls”
- 💡 In this class we will implement the actual logic.
- Start typing “b1-logicClass” and select the template.
- 💡 The code for method “myMethod” is created for you, and “myMethod” is automatically selected. Change this to the correct method name “getOrderInfo” by simply starting to type.
- 💡 B1 will automatically change all places in the code while you type. When you entered “getOrderInfo”, press TAB.
- 💡 B1 will automatically bring you to the next code-part that you need to change, the name of your Parameter-Class. Here we will use the Class we created in the previous step: OrderInfoParameter_<myName>.
- 💡Enter the name of your class and B1 will again automatically change it where necessary.
- 👋 Save your code.
- 💡 NOTE: If you get a syntax error, please add this line at the beginning of your file: using Consultingwerk.OERA.* from propath.
- 💡 In the Method (after the comment that says “enter your code here”) add the following logic:
METHOD PUBLIC VOID getOrderInfo(poParameter AS getOrderInfoParameter):
// enter your code here
DEFINE VARIABLE iCount AS INTEGER NO-UNDO.
iCount = RANDOM(1, 10).
ASSIGN poParameter:numOrders = iCount.
ASSIGN poParameter:Message = STRING(iCount) + " orders for customer " + STRING(poParameter:CustNum).
END METHOD.
- Execute a b1 trim
2.3 Implement the code in the UI that will call your ABL logic
- 👋 Go back to the Build.One Low-Code UI and open the Screen “TrainingDay5_OrderOverview”
- 👋 Open the Form “OrderForm_Training_Part5” (e.g. by using the “Open Master” feature in screen-designer, or using the “Forms” Desktop)
- 👋 In the Form-Designer select the Form itself (the root node in the tree), and then in the attributes set “Eventnamespace” to “#”
- 👋 Add a Button above the CustNum-Field, and set the “Enabled” Attribute to TRUE and the “Label” attribute to “get Order-Info”
- 👋For the “EventClick” Event add the following code:
- 👋In the ribbon select the button “</> Open events file”. A new file is opened in the workspace IDE for your OrderForm_Training. Switch to the file if it is not automatically selected.
- 👋Start typing “b1” in the created file and see the different code-templates you can use. Please select the “eventFunction” and press enter
- 👋Change the function name to “getOrderInfo”
- 👋Change the Parameter to “myButton: akioma.swat.Button” to specify that your function expects to be called from a Button.
- 👋 In the body of the function, type “B1-callBackend” and select “callBackendSync”.
- 💡 B1 will add the code to call your backend logic. “Sync” means “Synchronously”: Your UI-code will wait until the Backend-Code has returned.
- 💡 You could also use “callBackendAsync”, then your UI will immediately go to the next statement, and the backend logic will run in parallel (Asynchronoously).
- 💡 In our case, we want to work with the Result from our Backend-Code, hence we need to wait till it is finished. So “callBackendSync” is what we need for our use-case.
- 👋 Provide the correct Values for “name” and “methodName” and change the Function to look like this:
- 💡 (Hint add the async parameter in the eventFunction in order to use the await parameter)
#.getOrderInfo(eventSource)
Full Code Example:
export async function getOrderInfo(myButton: akioma.swat.Button) {
const oResult = await akioma.swat.App.invokeServerTask({
name: 'BusinessLogic.OrderLogic_<YourName>',
methodName: 'getOrderInfo',
paramObj: { plcParameter: {"custNum": 1} },
});
akioma.swat.Message.informationMessage (`Result: ${oResult.plcParameter.Message} `)
}
Here we have the parameters for our Backend-Logic hardcoded.
💡 To see your interim result do the following steps
- Click control + S to save and compile your result
- Go back to B1
- Refresh the page and empty the cache
- Launch your screen
- Click on the button
13. 👋 In the next step we want to pass in the actual customer. For this, we read the data from the UI. Change the code to look like this:
export async function getOrderInfo(myButton: akioma.swat.Button) {
const myForm = myButton.form as akioma.swat.Form;
const myDatasource = myForm.getLink("DISPLAY:SRC") as akioma.swat.DataSource;
const oResult = await akioma.swat.App.invokeServerTask({
name: 'BusinessLogic.OrderLogic_YourName',
methodName: 'getOrderInfo',
paramObj: { plcParameter: {"custNum": myDatasource.getValue("custnum")} },
});
akioma.swat.Message.informationMessage (`Result: ${oResult.plcParameter.Message} `)
}
💡Here, we figure out the form of the Button. Then we use the Blueprint to find the corresponding datasource. The getLink() function gives you at runtime access to the Flow-Part of the screen (The “Flow” Tab in the Screen-Designer).
💡Note: Instead of using the CustNum, one would use the Build.One “Handle”-Concept. Every Record has a Field “SelfHdl” which contains a character that uniquely identifies the record.
3 Explanation:
4 All working Code files as example
Order Info Parameter
BLOCK-LEVEL ON ERROR UNDO, THROW.
CLASS BusinessLogic.OrderInfoParameter_Alex
INHERITS Consultingwerk.JsonSerializable:
/* Input properties */
{ Akioma/Swat/JsonSerializableProperty.i custNum integer }.
/* Output properties */
{ Akioma/Swat/JsonSerializableProperty.i numOrders integer }.
{ Akioma/Swat/JsonSerializableProperty.i Message CHARACTER }.
CONSTRUCTOR PUBLIC OrderInfoParameter_Alex():
SUPER().
THIS-OBJECT:AddSerializableProperties("{&SerializableProperties}").
END CONSTRUCTOR.
END CLASS.
Order Logic
using BusinessLogic.* from propath.
using Consultingwerk.OERA.* from propath.
BLOCK-LEVEL ON ERROR UNDO, THROW.
CLASS BusinessLogic.OrderLogic_Alex
IMPLEMENTS Consultingwerk.OERA.IBusinessService, Consultingwerk.OERA.IBusinessTaskCatalogInfo:
METHOD PUBLIC Consultingwerk.OERA.IBusinessTaskCatalogData GetCatalogData():
DEFINE VARIABLE oCatalog AS Consultingwerk.OERA.BusinessTaskCatalogData NO-UNDO.
oCatalog = NEW Consultingwerk.OERA.BusinessTaskCatalogData(THIS-OBJECT:GetClass():TypeName,
"getOrderInfo", GET-CLASS(OrderInfoParameter_Alex)).
RETURN oCatalog.
END METHOD.
METHOD PUBLIC VOID getOrderInfo(poParameter AS OrderInfoParameter_Alex):
// enter your code here
DEFINE VARIABLE iCount AS INTEGER NO-UNDO.
iCount = RANDOM(1, 10).
ASSIGN poParameter:numOrders = iCount.
ASSIGN poParameter:Message = STRING(iCount) + " orders for customer " + STRING(poParameter:CustNum).
END METHOD.
END CLASS.
Forntend Class Hard Coded
export async function getOrderInfo(myButton: akioma.swat.Button) {
const oResult = await akioma.swat.App.invokeServerTask({
name: 'BusinessLogic.OrderLogic_Alex',
methodName: 'getOrderInfo',
paramObj: { plcParameter: {"custNum": 1} },
});
akioma.swat.Message.informationMessage (`Result: ${oResult.plcParameter.Message} `)
Frontend Class Dynamic
export async function getOrderInfo(myButton: akioma.swat.Button) {
const myForm = myButton.form as akioma.swat.Form;
const myDatasource = myForm.getLink("DISPLAY:SRC") as akioma.swat.DataSource;
const oResult = await akioma.swat.App.invokeServerTask({
name: 'BusinessLogic.OrderLogic_Alex',
methodName: 'getOrderInfo',
paramObj: { plcParameter: {"custNum": myDatasource.getValue("custnum")} },
});
akioma.swat.Message.informationMessage (`Result: ${oResult.plcParameter.Message} `)
}