Enterprise Resource Planning Portal ERPGenie.COM Enterprise Resource Planning Portal

   Advertise | BLOG

Web ERPGenie.COM

Home | Vote for us |

ERPGenie.COM -> SAP Interfacing Technology -> ITS -> Development -> ITS Flow Logic

This model allows you to develop Internet applications that consist of linked HTML pages, which you can populate with data retrieved from the R/3 System (or any other external system). The pages can offer a range of application functions, and are generated by following hyperlinks or processing HTML forms. The dialog flow is determined on the client side by the user, who can navigate freely between pages.

Since the dialog flow is not fixed in advance, much depends on what the user decides to do. This contrasts with the dialog flow in other business scenarios, where the business application can put restrictions on how users can navigate.

Like all other implementation models, there is a clear separation between business logic and presentation aspects. In this case, defining the dialog flow is also a separate task.

Quicklinks

You implement a set of modules that comprise the business logic in the R/3 System (or other external system).

If you are implementing the business logic in the R/3 System, you create Business APIs (BAPIs) or standard remote-enabled function modules with the Function Builder in the ABAP Workbench. This tutorial uses remote-enabled function modules.

You implement the presentation and the dialog flow in the SAP@Web Studio.

To do this, you need to create an ITS service, which contains all the files required to implement and run the application.

    • The presentation determines the look and feel of each application.

You design the presentation by creating a set of HTMLBusiness templates.

    • The dialog flow determines which template is displayed when, depending on what the user decides to do next.

You implement the dialog flow by defining flow logic in flow files. Flow logic operates like a state machine, because it defines the sequence in which modules are called based on events and exceptions.

There is one flow file for each HTMLBusiness template that requires a dialog flow definition.

Example ITS Flow Logic - Sales Order Creation (© 2002 Computerservice Wolf - all rights reserved.)

STEP 1 - Requirements

Company A has a product catalog on the internet, which is implemented in PHP and mySQL. This catalog should be extended with the option to create a sales order. SAP ITS can be used to achieve this as long as the back-end ERP system is SAP.

STEP 2 - Preparation

  • Download and install the ITS (www.saplabs.com)

  • Install SAP@Web Studio (www.saplabs.com). Starting from release 4.6C you can use the Web Application Builder in the ABAP workbench to achieve the same functionality as web studio.

STEP 3 -Implementation

You should consider using this implementation model for applications that offer many application functions on one page, and the dialog flow is not fixed in advance.

Such applications have simple point-and-click user interfaces, limited manual data input, and reduced data formatting requirements. They are often used in e-commerce scenarios.

Data transfer from the product catalog

We use an HTML form (and HTTP POST) as the interface between the product catalog and the ITS flow logic application.

<form ACTION="http://its.domain.com/scripts/wgate/z_order_in/!?~language=en" METHOD="POST">

Qty: <input type="text" name="ORDER_ITEMS_IN-REQ_QTY[1]"><br>

Material: <input type="text" name="ORDER_ITEMS_IN-MATERIAL[1]"><br>

<input type="submit" name="Place Order" value="ORDER">

</form>

The form looks like this:

Qty:

Material:

Definition of the ITS Service

The ITS service is called z_order_in and has the following content:

~ZGatewaysapxginetimplies flow logic application
~languagethis value will be set in the URL
~initialTemplateloginstartup page
~theme99sets the look and feel of the web app

Log-on to SAP as an internet user

1.1. LOGIN.HTML

The login page asks the customer to enter his customer number and the password. You maintain these 2 values in SAP using SU05 (object for customer) and XD01 (create customer master record).

<html>

<head>

<title>`#order_in_login`</title>

</head>

<body>

<form method=post action=`wgateURL()`>

<table>

<tr>

<td>`#KUNNR`</td>

<td><input type=text name="CUSTOMERNO" value="`CUSTOMERNO`"></td>

</tr>

<tr>

<td>`#PASSWORD`</td>

<td><input type=password name="PASSWORD"></td>

</tr>

<tr>

<td>

<input type="hidden" name="SALES_ORGANIZATION" value ="1000">

<input type="hidden" name="DISTRIBUTION_CHANNEL" value ="10">

<input type="hidden" name="DIVISION" value ="10">

`repeat with i from 1 to ORDER_ITEMS_IN-MATERIAL.dim`

<input type="hidden" name="ORDER_ITEMS_IN-MATERIAL[`i`]" value ="`ORDER_ITEMS_IN-MATERIAL[i]`">

<input type="hidden" name="ORDER_ITEMS_IN-REQ_QTY[`i`]" value ="`ORDER_ITEMS_IN-REQ_QTY[i]`">

`end`

<input type="submit" name="~event=login" value=`#login`">

</td>

</tr>

</table?

</form>

<h2>`#Messages`</h2>

`RETURN-MESSAGE`<br>

</body>

</html>

1.2. LOGIN FLOW FILE

<flow>

<event name="login" next_state="checkCustomerNumber">

</event>

<state name="checkCustomerNumber">

<module name="BAPI_CUSTOMER_CHECKEXISTENCE" stateful="0" type="RFC">

<result next_state="checkPassword">

<expr>

RETURN-TYPE==""

</expr>

</result>

<persistent name="CUSTOMER_NUMBER_OUT"/>

<persistent name="SALES_ORGANIZATION"/>

<persistent name="DISTRIBUTION_CHANNEL"/>

<persistent name="DIVISION"/>

<persistent name="lang"/>

<persistent name="javascript"/>

<persistent name="session"/>

</module>

</state>

<state name="checkPassword">

<module name="BAPI_CUSTOMER_CHECKPASSWORD" stateful="0" type="RFC">

<result next_template="simulate">

<expr>

RETURN-TYPE==""

</expr>

</result>

</module>

</state>

</flow>

First the BAPI_CUSTOMER_CHECKEXISTENCE is called in order to check whether the customer number exists. If this is true then the password is checked with BAPI_CUSTOMER_CHECKPASSWORD. If this is true then the template "simulate" is called. In all other cases the error message is displayed through the structure RETURN referencing field MESSAGE.

Simulate the order

2.1. SIMULATE.HTML

<html>

<head>

<title>`#simulate_order`</title>

</head>

<body>

RETURN-TYPE: `RETURN-TYPE`<br>

RETURN-MESSAGE: `RETURN-MESSAGE`<br>

RETURN-CODE: `RETURN-CODE`<br>

<table border="1">

<tr>

<td>`#material`</td>

<td>`#quantity`</td>

<td>`#price`</td>

</tr>

`repeat with i from 1 to ORDER_ITEMS_OUT-MATERIAL.dim`

<tr>

<td>`ORDER_ITEMS_OUT-MATERIALS[i]`</td>

<td>`ORDER_ITEMS_OUT-REQ_QTY[i]`</td>

<td>`ORDER_ITEMS_OUT-SUBTOTAL_2[i]/1000`</td>

</tr>

`end`

</table>

<form action="`wgateURL()`" method="POST">

`repeat with i from 1 to ORDER_ITEMS_IN-MATERIAL.dim`

<input type="hidden" name="ORDER_ITEMS_IN-MATERIAL[`i`]" value="`ORDER_ITEMS_IN-MATERIAL[i]`">

<input type="hidden" name="ORDER_ITEMS_IN-REQ_QTY[`i`]" value="`ORDER_ITEMS_IN-REQ_QTY[i]`">

`end`

<input type="submit" name="~event=shipto" value="`#shipto`">

<input type="submit" name="~event=order" value="`#order`">

</form>

</body>

</html>

2.1.1. GET DATE TIME FUNCTION MODULE

To start the simulation with BAPI_SALESORDER_SIMULATE many other additional fields in the structure ORDER_HEADER_IN and the tables ORDER_PARTNERS and ORDER_ITEMS_IN must be filled. Some fields must contain the current date. To get the current date use the custom RFC Z_GET_DATE:

function z_get_date

* importing

*   value(dayspast) like mara-matnr default 0

*   value(timepast) like mara-matnr default 0

* exporting

*   value(date) like sy-datum

*   value(time) like sy-uzeit

 

date = sy-datum - dayspast.

time = sy-uzeit - timepast.

 

endfunction.

2.1.2. HTML Business Script INIT

The table and structures are filled through the HTML Business script init:

`

ORDER_HEADER_IN-DOC_TYPE = 'ZOR';

ORDER_HEADER_IN-SALES_ORG = SALES_ORGANIZATION;

ORDER_HEADER_IN-DISTR_CHAN = DISTRIBUTION_CHANNEL;

ORDER_HEADER_IN-DIVISION = DIVISION;

ORDER_HEADER_IN-CD_VALUE1 = "0.00";

ORDER_HEADER_IN-CD_VALUE2 = "0.00";

ORDER_HEADER_IN-CD_VALUE3 = "0.00";

ORDER_HEADER_IN-CD_VALUE4 = "0.00";

ORDER_HEADER_IN-PRICE_DATE = DATE;

ORDER_HEADER_IN-QT_VAILD_F = DATE;

ORDER_HEADER_IN-QT_VAILD_T = DATE;

ORDER_HEADER_IN-CT_VAILD_F = DATE;

ORDER_HEADER_IN-CT_VAILD_T = DATE;

ORDER_PARTNERS-PARTN_ROLE[1] = "AG";

ORDER_PARTNERS-PARTN_NUMB[1] = CUSTOMER_NUMBER_OUT;

ORDER_PARTNERS-ITM_NUMBER[1] = "000000";

if (ORDER_PARTNERS-NAME[2] != "")

ORDER_PARTNERS-PARTN_ROLE[2] = "WE";

ORDER_PARTNERS-PARTN_NUMB[2] = CUSTOMER_NUMBER_OUT;

ORDER_PARTNERS-ITM_NUMBER[2] = "000000";

end;

repeat with i from 1 to ORDER_ITEMS_IN-MATERIAL.dim

ORDER_ITEMS_IN-COND_VALUE[i] = "0.00";

ORDER_ITEMS_IN-COND_VAL1[i] = "0.00";

ORDER_ITEMS_IN-CD_VALUE1[i] = "0.00";

ORDER_ITEMS_IN-CD_VALUE2[i] = "0.00";

ORDER_ITEMS_IN-CD_VALUE3[i] = "0.00";

ORDER_ITEMS_IN-CD_VALUE4[i] = "0.00";

end;

`

2.2. SIMULATE FLOW FILE

After the successful simulation of the sales order the customer has the option to order either directly or to set a different ship-to address.

<flow>

<state name="simulate">

<module name="BAPI_SALESORDER_SIMULATE" stateful="0" type="RFC">

</module>

</state>

<state name="init">

<module name="init" stateful="0" type="SCRIPT">

<default next_state="simulate">

</default>

</module>

</state>

<event name="ontouch" next_state="dateget">

</event>

<state name="dateget">

<module name="Z_GET_DATE" stateful="0" type="RFC">

<default next_state="init">

</default>

</module>

</state>

<event name="order" next_template="order">

</event>

<event name="shipto" next_template="shipto">

</event>

</flow>

Change the ship to address

3.1. SHIPTO.HTML

Through this template a different ship-to address can be set. The material number and quantity are again transferred in hidden fields.

<html>

<head>

<title>`#shipto`</title>

</head>

<body>

<form action="`wgateURL()`" method="POST">

`repeat with i from 1 to ORDER_ITEMS_IN-MATERIAL.dim`

<input type="hidden" name="ORDER_ITEMS_IN-MATERIAL[`i`]" value="`ORDER_ITEMS_IN-MATERIAL[i]`">

<input type="hidden" name="ORDER_ITEMS_IN-REQ_QTY[`i`]" value="`ORDER_ITEMS_IN-REQ_QTY[i]`">

`end`

<table>

<tr>

<td>Name1:</td>

<td><input type=text name="ORDERS_PARTNERS-NAME[2]" maxlength=35></td>

</tr>

<tr>

<td>Name2:</td>

<td><input type=text name="ORDERS_PARTNERS-NAME_2[2]" maxlength=35></td>

</tr>

<tr>

<td>Name3:</td>

<td><input type=text name="ORDERS_PARTNERS-NAME_3[2]" maxlength=35></td>

</tr>

<tr>

<td>Name4:</td>

<td><input type=text name="ORDERS_PARTNERS-NAME_4[2]" maxlength=35></td>

</tr>

<tr>

<td>Street:</td>

<td><input type=text name="ORDERS_PARTNERS-STREET[2]" maxlength=35></td>

</tr>

<tr>

<td>ZIP:</td>

<td><input type=text name="ORDERS_PARTNERS-POSTL_CODE[2]" maxlength=35></td>

</tr>

<tr>

<td>City:</td>

<td><input type=text name="ORDERS_PARTNERS-CITY[2]" maxlength=35></td>

</tr>

<tr>

<td>Country:</td>

<td><input type=text name="ORDERS_PARTNERS-LAND[2]" maxlength=35></td>

</tr>

</table>

<input type="submit" name="~event=order" value="`#order`">

</form>

</body>

</html>

3.2. SHIPTO FLOW FILE

<flow>

<event name="order" next_template="order">

<!--*FlowDesigner bounds (-100, 8, 100, 10)*-->

</event>

</flow>

Show the order confirmation

4.1. ORDER.HTML

After the successful posting of the sales order, the data and order number need to be displayed.

<html>

<head>

<title>`#order`</title>

</head>

<body>

<pre>

`#Soldtoname`:          `SOLD_TO_PARTY-NAME`

`#Soldtostreet`:          `SOLD_TO_PARTY-STREET`

`#SoldtoZIP`:             `SOLD_TO_PARTY-POSTL_CODE`

`#Soldtocity`:             `SOLD_TO_PARTY-CITY`

 

`#Shiptoname`:          `SHIP_TO_PARTY-NAME`

`#Shiptostreet`:          `SHIP_TO_PARTY-STREET`

`#ShiptoZIP`:             `SHIP_TO_PARTY-POSTL_CODE`

`#Shiptocity`:             `SHIP_TO_PARTY-CITY`

 

<table border="1">

<tr>

<td>`#role`</td>

<td>`#kunnr`</td>

<td>`#item_numb`</td>

<td>`#name`</td>

<td>`#street`</td>

<td>`#zip`</td>

<td>`#city`</td>

</tr>

`repeat with i from 1 to ORDER_PARTNERS-NAME.dim`

<tr>

<td>`ORDER_PARTNERS-PARTN_ROLE[i]`</td>

<td>`ORDER_PARTNERS-PARTN_NUMB[i]`</td>

<td>`ORDER_PARTNERS-ITM_NUMBER[i]`</td>

<td>`ORDER_PARTNERS-NAME[i]`</td>

<td>`ORDER_PARTNERS-STREET[i]`</td>

<td>`ORDER_PARTNERS-POSTL_CODE[i]`</td>

<td>`ORDER_PARTNERS-CITY[i]`</td>

</tr>

`end`

</table>

 

RETURN-TYPE:          `RETURN-TYPE`

RETURN-MESSAGE:   `RETURN-MESSAGE`

RETURN-CODE:         `RETURN-CODE`

`#salesdocument`:   `SALESDOCUMENT`

</pre>

</body>

</html>

4.2. ORDER FLOW FILE

To create the sales order the BAPI BAPI_SALESORDER_CREATEFROMDATA is called. This RFC has the same interface as the BAPI_SALESORDER_SIMULATE so we need to call the script "init". In the script there is a check to see if a different ship to was entered, which must be supplied with additional values accordingly.

<flow>

<state name="simulate">

<module name="BAPI_SALESORDER_CREATEFROMDATA" stateful="0" type="RFC">

</module>

</state>

<state name="init">

<module name="init" stateful="0" type="SCRIPT">

<default next_state="simulate">

</default>

</module>

</state>

<event name="ontouch" next_state="getdate">

</event>

<state name="getdate">

<module name="Z_GET_DATE" stateful="0" type="RFC">

<default next_state="init">

</default>

</module>

</state>

</flow>

Note:

In 4.0B the BAPI BAPI_SALESORDER_CREATEFROMDATA has as error when a different ship to address is entered. The ZIP is not transferred. To correct this apply OSS note 0441210)

 

Contact Us | Polls | Add URL | Contribute | About | Privacy | Terms | Feedback | Help!

Message Board | Discussion Forum | BLOG | Consultants: Post your resume | Companies: Advertise on ERPGenie.COM | Post Job