You are on page 1of 44

Classy Workflows

Mike Pokraka, Independent Anna Hill, SAP UK

Learning Points
Understand the differences between using BOR and Classes for workflow Understand why classes are being used in workflow

How to build a class and implement it in a workflow

By end the this presentation, you should have the knowledge and confidence to use a class in a workflow even if the workflow currently uses business objects!

Agenda
Introduction To Using Classes
Creating Utility Classes

Creating Business Classes


Mixing Classy and BORing objects

Conclusion

Agenda
Introduction To Using Classes
Creating Utility Classes

Creating Business Classes


Mixing Classy and BORing objects

Conclusion

Introduction
Target audience:
Workflow developers who want to learn how to use a class in a workflow

Demo System:
NW04s Technology Preview (Test Drive) Yes, YOU can install it and try all examples yourself!

Assumptions:
Complex topic in a 1 hour presentation Functional & realistic examples, but not always best practice e.g. No error handling Using SAP NetWeaver release 6.20 or above

History of Objects
ABAP Classes
ABAP becomes object oriented Workflow can use ABAP Classes with limitations Classes are fully useable and supported Classes used in SAP delivered workflows for the first time

3.0c
Workflow appears BOR created to emulate OO since ABAP was completely procedural

4.6c

6.20

NW04

NW04s

Business content had grown to over 1000 BOR object types

Very little new BOR development

Classic BOR

Still same archaic BOR editor. Strongest hint yet that active development has ceased?

Why Use Classes?


Its the way forward! Standard SAP starting to use classes Modern editor & improved coding standards Clever bindings using functional methods

Usage not limited to workflow


Maintainable by developers without workflow knowledge Adding additional components to classes is really easy!

Why Not?!
More up front DIY when creating the class Knowledge of OO essential (but not hard to pick up!) 1000+ BOR Object Types exist and can still be used Older versions of SAP do not support OO Classes

Object-Oriented Design
Objects should be modelled to represent real-world equivalents Encapsulation ensures logic and data is selfcontained and not directly accessible or visible from the outside, unless required

Object-Oriented Design
Attributes are an objects data made visible to the outside world

DocumentNo CompanyCode Plant CreatedBy

Object-Oriented Design
Methods are actions that can be performed on the object

Display
DocumentNo CompanyCode Plant CreatedBy Change Print

Object-Oriented Design
Events are changes in an objects status Broadcast to entire system
Display
DocumentNo CompanyCode Plant CreatedBy Change Print
Changed Created Blocked

Basic Comparison
Compare:
Interfaces:

Business Objects
Already implemented in standard Key Fields (LPOR is handled internally) Instance / Instance-Independent Hierarchy: Type Object Public/Private Multiline Read-only (Value populated in attribute code)

Business Classes
Must code components of IF_WORKFLOW yourself LPOR (Local Persistent Object Reference) Instance / Static Hierarchy: Type ref to Public/Private Table type (from Data dict.) Read/Write (Value populated in methods, function like variables)

Unique Identification:

Component Level: Attributes:

Methods:

Import/Export/Result Dialog/background Synchronous/Asynchronous

Import/Export/Returning (Func.) Controlled by task Controlled by task


As per BOR

Events:

Communication link

Agenda
Introduction To Using Classes
Creating Utility Classes

Creating Business Classes


Mixing Classy and BORing objects

Conclusion

Whats a Utility Class?


Does not need to be instantiated Contains cross application functionality Examples:
Decision Form/Webservice

Specifically:
Attributes
URL of SRM system System Date/time

Methods
Execute Rule Notification (we will see this) Calculate deadline using factory calendar

Interface IF_WORKFLOW
This interface must be implemented for workflow Provides the following functions:
Interfaces:
BI_OBJECT BI_PERSISTENT

Methods:
FIND_BY_LPOR LPOR REFRESH DEFAULT_ATTRIBUTE_VALUE EXECUTE_DEFAULT_METHOD RELEASE

(like SWC_REFRESH_OBJECT)

(for garbage collection)

NOTE: Methods must be implemented, even if no code required

A Simple Workflow Example


New employee must confirm they have read company rules

BOR Implementation

Demo: Creating the class


Add interface IF_WORKFLOW

Add methods

Create empty interface methods

Add NOTIFY method also without code

Demo: Add Task to WF


Create Task Based on Class Add Text

Synchronous and Confirm only available after saving

Agenda
Introduction To Using Classes
Creating Utility Classes

Creating Business Classes


Mixing Classy and BORing objects

Conclusion

Creating Business Classes


Key difference with Utility Class:
Must be instantiated using a key Local Persistent Object Reference

Constructor method:
Used to populate public attributes Contains existence check

Recommendation: Create method GET_INSTANCE equivalent to SYSTEM.GENERICINSTANTIATE

Persistent vs. Runtime

Persistent
Workflow system calls FIND_BY_LPOR to get instance
Only object key is stored in database Workflow system calls LPOR to get key

Runtime
Object instance in memory has attributes and methods can be executed

Implementing LPOR
Switching between persistent (DB) and runtime (memory) Done automatically in BOR One is the reversal of the other:
1. 2. FIND_BY_LPOR: Have key LPOR: Have object Need object Need key

method BI_PERSISTENT~FIND_BY_LPOR. * Called by workflow to request an object instance data: lv_user type ref to zcl_wf_user, lv_id type xubname. lv_id = lpor-instid. create object lv_user exporting im_userid = lv_id. result = lv_user. endmethod.

method BI_PERSISTENT~LPOR. * Called by workflow requesting an instance's key result-catid = 'CL'. result-typeid = 'ZCL_WF_USER'. result-instid = userid. endmethod.

Attributes
Attributes in classes work like variables Must be set in CONSTRUCTOR method Recommended to flag as read-only

Method CONSTRUCTOR. *-- Select key table data into private attribute select single * from usr01 into m_usr01 where bname = im_userid. check sy-subrc = 0.
*-- Populate public attributes: * userid userid = im_userid. * Language select single sptxt from t002t into where spras = sy-langu and sprsl = m_usr01-langu. endmethod.

Performance Note: Avoid for complex attributes that arent always needed, as this is executed for each instance whether the attribute is used or not

language

Functional Methods (NW04)


Method with one returning parameter Can have importing but no exporting parameters Naming convention: GET_<value>
e.g. GET_EMAIL_ADDRESS

Can be used in bindings and container operations Can NOT be used in Workitem Texts
Bind to separate task container element instead

Functional Methods contd.


Returning Parameter

method GET_EMAIL_ADDRESS. *--- Get user's email address from address management select single adr6~smtp_addr into re_email from usr21 inner join adr6 on adr6~persnumber = usr21~persnumber and adr6~addrnumber = usr21~addrnumber where usr21~bname = userid. endmethod.

Functional Method displayed as attribute


Do not use, does not work at present (NW04s SP08)

Functional Method displayed as method

Demo: User Business Class


Already seen in utility classes:
Creating basic workflow-enabled class (i.e. interface implemented) Creation of method

Now we need to:


Create key attribute USERID Create private attribute:
USR01 database record (like perform select_table)

Create public attributes:


Email address (Functional Method equivalent to virtual attribute) 640 Language (equivalent to database attribute) 620

Create Constructor method


Existence check, inc get DB record for key field Populate public attributes

LPOR / Find by LPOR

Agenda
Introduction To Using Classes
Creating Utility Classes

Creating Business Classes


Mixing Classy and BORing objects

Conclusion

Extending Classes
A class can contain a BO attribute reference but not the other way around i.e.
Class can refer to a BO BO cannot refer to a class

Extend business classes with BO


Used to convert traditional workflow to classy workflow Type SIBFLPORB identifies this a s a BOR object e.g. add USR01 Business object to ZCL_WF_USER

Must use complete BO in tasks


i.e. cannot access CLASSBOATTRIBUTE directly Bind CLASSBO to task and use BOATTRIBUTE in task

Demo: Adding BOR


Add Attribute BO_USR01

...and populate it in the CONSTRUCTOR


Method CONSTRUCTOR. .... * Business Object bo_usr01-catid bo_usr01-typeid bo_usr01-instid endmethod. USR01 in attrib BO_USR01 = 'BO'. = 'USR01'. = userid.

Demo: Using Classy BOR


Add importing container element for BO Use BO as usual - as main task object or as text expression

Bind BO attribute to task object (Note that BO cannot be expanded further)

Agenda
Introduction to Using Classes
Creating Utility Classes

Creating Business Classes


Mixing Classy and BORing objects

Conclusion

Key Learnings
Map traditional BOR concepts to class equivalents Create a basic utility class for X-app functionality Create a business class and extend with BO/utility class Integrate classes into workflows

Convert BO workflows to classy workflows

Appendix: Limitations
Some limitations exist in 6.20: Cant use functional methods Some navigation quirks, e.g. cannot look at multiline class elements.
Tip: create single element attribute corresponding to any table attributes. e.g. If you have an ITEMS attribute, also create an ITEM_1 to aid debugging seeing the first one is better than none.

Appendix: More comparisons


Function:
Interface IF_WORKFLOW Method DEFAULT_ATTRIBUTE_VALUE Method EXECUTE_DEFAULT_METHOD Method RELEASE Method FIND_BY_LPOR Method LPOR Method REFRESH

Class Meaning
Defines essential components Default attribute Default method

BOR Equivalent
Interface IF_SAP Basic data: default attribute Basic data: default method

Destructor, called when WF is done with object (not necessary) Switch: persistent to runtime (DB to memory) Switch: persistent to runtime (memory to DB) Reload from DB, needs to be implemented in the class

Not available in BOR / internal N/A in BOR, done automatically swc_persistent_to_memory N/A in BOR, done automatically swc_memory_to_persistent Macro SWC_REFRESH_OBJECT on SELF

Key Attribute Column

Enables attribute to be marked as key

key fields

Appendix: Coding Syntax


Function:
Reference Self

Class Syntax
Instance: Static: -> =>

BOR Macro
Implemented using macros self

me (note: can usually be omitted if not ambiguous, e.g. me->attr is same as just attr.

Read Attribute: self

l_var = attrib. (or l_var = me->attrib)


l_var = l_obj->attrib attrib = <value>. meth( ). l_obj->meth( ). l_var = meth( ).

swc_get_element self Attrib l_var.


swc_get_element l_obj Attrib l_var. No can do! swc_call_method obj Meth container. No such thing.

other object Write Attribute Call Method self other Read functional method

Appendix: Events
Class events used in the same way as object events Can be seen in the event trace Event triggering config. enabled for classes?
SWEC BSVW SWEHR1/2/3 Message Control SWE_EVENT_CREATE yes (from 6.40) no no no no

Tips and Tricks


Method code must be implemented as per BOR Constructor - Business class: called when instantiated Attribute initial value equivalent to hard-coding in virtual attribute CX_BO- exception classes for workflow (se SE24) Method Get_Instance - Custom method to generate instance of class, alternative to using SWC_CREATE_OBJECT Synchronous tasks must explicitly check flag; not pulled through automatically from method

Best Practices
New SAP standard delivered workflow functionality class based To ensure well defined, compatible workflows, workflow developers required ability to enhance and implement class based workflows Programming in workflow will no longer be restricted to developers with BOR knowledge

Additional Information
SAP Online Help NW04s Search for Workflow API
Note: Not available in older versions, but still applicable

Jocelyn Darts blogs


https://www.sdn.sap.com/irj/sdn/weblogs?blog=/pub/wlg/4662

SDN BPM and Workflow Forum

Q&A

Session Code: Insert session code

You might also like