Creating a Custom Genil/Bol object Model
Defining and Creating a Genil Model :
You could define and implement dynamic models using IF_GENIL_APPL_MODEL Interface.
use GENIL_MODEL_EDITOR OR GENIL_MODEL_BROWSER to create static models ,
As Genil component class extends default implementation of IF_GENIL_APPLMODEL_PERSISTENCY namely CL_WCF_GENIL_ABSTR_COMPONENT.
Step 1 : Go to Transaction SE24 or SE80 ,Create a new abap Custom Genil Class
ZCL_CUSTOMER_MODEL
As this class use statically defined model we inherit from CL_WCF_GENIL_ABSTR_COMPONENT.
Save and activate the class.
Step 2: Registering of Genil component is done using Transaction SM34 ,
Enter View Cluster name as CRMVC_GIL_APPDEF or we can use maintaince view CRMV_GIL_COMP
Click maintain button.
Maintain the entries for Component Definition , Component Set Definition and Component Assignment.
Step 3: Create a new Master Table name as ZMAST_CUST using transaction SE11.
Creating a Genil Business Objects.
Key Structure of Customer Data.
Attribute structure of a Customer Data
Table Type of Attribute Structure.
Create a Lock object of master table ZMAST_CUST.
Step 4 : Go to Transaction GENIL_MODEL_BROWSER,
Give component name as ZCUST .
- a.) Click on Change button and Right Click on Root Objects -> Give Object Name as Customer
Add Key Structure Name , Attribute structure name and Create structure name .
And check web service enabled.
Keep Attribute Structure Property -in Changeable mode , So that while creating a object you can see a list of fields in Change mode in Object Browser .
Step 5 : Open a custom genil class ZCL_CUSTOMER_MODEL and redefine all this metohods as shown below.
Create a new custom class name as ZCL_CUSTOMER_API which will to hold the API methods to retrieve data from database.
Declare GT_CUSTOMER as a global attributes ZATTR_CUST_TAB ( Attribute Structure of Customer ) of ZCL_CUSTOMER_API
Here’s the coding Starts to create a new root object
IF_GENIL_APPL_INTLAY~CREATE_OBJECTS
METHOD if_genil_appl_intlay~create_objects.
TYPES : BEGIN OF ty_cust,
custno TYPE zcustno,
END OF ty_cust.
DATA : lv_guid TYPE crmt_object_guid.
DATA : lv_key TYPE zattr_cust_key.
DATA : lv_success TYPE char1.
DATA : lit_cust TYPE TABLE OF ty_cust.
DATA : wa TYPE ty_cust.
DATA : lv_count TYPE i VALUE 0.
* Fill structure based on Name Value Pairs Table.
fill_struct_from_nvp_tab( EXPORTING it_parameters = it_parameters
CHANGING cs_parameter = lv_key ).
* Creating a Guid.
CALL FUNCTION ‘GUID_CREATE’
IMPORTING
ev_guid_16 = lv_guid.
* Custom Logic to create a New Customer Number.
SELECT custno FROM zmast_cust INTO TABLE lit_cust.
SORT lit_cust DESCENDING.
IF lit_cust IS NOT INITIAL.
LOOP AT lit_cust INTO wa.
lv_count = wa–custno + 1.
EXIT.
ENDLOOP.
ELSE.
lv_count = 1.
ENDIF.
lv_key–guid = lv_guid.
lv_key–custno = lv_count.
* API Class fills the the global attribute.
CALL METHOD zcl_customer_api=>create_customer
EXPORTING
is_cust_key = lv_key
IMPORTING
rv_success = lv_success.
* Add the object to Data Container – Root Object List Interface
IF lv_success IS NOT INITIAL.
iv_root_list->add_object( iv_object_name = iv_object_name
is_object_key = lv_key ).
ENDIF.
ENDMETHOD.
METHOD CREATE_CUSTOMER.
DATA : lv_data like line OF gt_customer.
* First step is to Lock a Customer.
CALL FUNCTION ‘ENQUEUE_EZMAST_CUST’
EXPORTING
mode_zmast_cust = ‘E’
EXCEPTIONS
foreign_lock = 1
system_failure = 2
OTHERS = 3.
IF sy–subrc <> 0.
* Implement suitable error handling here
ENDIF.
* Writing to Buffer values passed by parameters and setting Flag C.
lv_data–guid = is_cust_key–guid.
lv_data–custno = is_cust_key–custno.
lv_data–new = ‘C’.
append lv_data to gt_customer.
rv_success = ‘X’.
ENDMETHOD.
IF_GENIL_APPL_INTLAY~GET_OBJECTS.
METHOD if_genil_appl_intlay~get_objects.
DATA lv_root TYPE REF TO if_genil_cont_root_object.
DATA lv_key TYPE zattr_cust_key.
DATA lv_cust_att TYPE zattr_cust.
* Get the first object of data container.
lv_root = iv_root_list->get_first( ).
lv_root->get_key( IMPORTING es_key = lv_key ).
* Check if attributes are read after Create
IF lv_root->check_attr_requested( ) = abap_true.
* Custom API class to get the customer attributes.
zcl_customer_api=>get_customer( EXPORTING is_cust_key = lv_key
IMPORTING es_cust_attr = lv_cust_att ).
* Return the objects only if it exists
IF lv_cust_att IS NOT INITIAL.
* Set the attributes in container
lv_root->set_attributes( lv_cust_att ).
* Get the next object of data container.
lv_root = iv_root_list->get_next( ).
ENDIF.
ENDIF.
ENDMETHOD.
METHOD get_customer.
FIELD-SYMBOLS <data> LIKE LINE OF gt_customer.
*
IF is_cust_key IS NOT INITIAL.
* Try to read from Buffer.
READ TABLE gt_customer WITH KEY
guid = is_cust_key–guid
custno = is_cust_key–custno
ASSIGNING <data>.
ELSE.
READ TABLE gt_customer WITH KEY new = ‘C’ ASSIGNING <data>.
IF sy–subrc <> 0.
RETURN.
ENDIF.
ENDIF.
IF sy–subrc = 0.
IF <data>–new EQ ‘C’ OR <data>–new EQ ‘M’.
MOVE-CORRESPONDING <data> TO es_cust_attr.
RETURN.
ENDIF.
ENDIF.
ENDMETHOD.
IF_GENIL_APPL_INTLAY~MODIFY_OBJECTS
METHOD if_genil_appl_intlay~modify_objects.
DATA : lv_cust_attr TYPE zattr_cust,
lv_root TYPE REF TO if_genil_container_object,
lv_changed_objects TYPE crmt_genil_obj_instance,
lv_props TYPE REF TO if_genil_obj_attr_properties,
lt_changed_attr TYPE crmt_attr_name_tab,
lv_cust_key TYPE zattr_cust_key,
lv_success TYPE abap_bool.
DATA : lv_change TYPE crmt_genil_attr_property.
CHECK iv_root_list IS BOUND.
* Get the first object from Container.
lv_root = iv_root_list->get_first( ).
IF lv_root->get_delta_flag( ) IS NOT INITIAL.
* Get name of the object.
CASE lv_root->get_name( ).
WHEN ‘Customer’.
* Returns an Property Object for Object Attributes.
lv_props = lv_root->get_attr_props_obj( ).
* Returns a Table of All Names with Specified Property.
CALL METHOD lv_props->get_name_tab_4_property
EXPORTING
iv_property = if_genil_obj_attr_properties=>modified
IMPORTING
et_names = lt_changed_attr.
lv_root->get_key( IMPORTING es_key = lv_cust_key ).
lv_root->get_attributes( IMPORTING es_attributes = lv_cust_attr ).
MOVE-CORRESPONDING lv_cust_key TO lv_cust_attr.
CALL METHOD zcl_customer_api=>change_customer
EXPORTING
is_cust_attr = lv_cust_attr
it_names = lt_changed_attr
IMPORTING
rv_success = lv_success.
IF lv_success IS NOT INITIAL.
lv_changed_objects–object_name = ‘Customer’.
lv_changed_objects–object_id = cl_crm_genil_container_tools=>build_object_id( lv_cust_key ).
* Add into Object Table with Object Type and ID.
APPEND lv_changed_objects TO et_changed_objects.
ENDIF.
WHEN OTHERS.
ENDCASE.
ENDIF.
ENDMETHOD.
METHOD change_customer.
FIELD-SYMBOLS : <line> TYPE zattr_cust,
<old> TYPE simple,
<new> TYPE simple,
<name> TYPE name_komp.
READ TABLE gt_customer WITH KEY
guid = is_cust_attr–guid
custno = is_cust_attr–custno ASSIGNING <line> .
CHECK sy–subrc IS INITIAL.
LOOP AT it_names ASSIGNING <name>.
ASSIGN COMPONENT <name> OF STRUCTURE <line> TO <old>.
CHECK sy–subrc = 0.
ASSIGN COMPONENT <name> OF STRUCTURE is_cust_attr TO <new>.
CHECK sy–subrc = 0.
<old> = <new>.
ENDLOOP.
<line>–new = ‘M’.
rv_success =‘X’.
ENDMETHOD.
IF_GENIL_APPL_ALTERNATIVE_DSIL~SAVE_OBJECTS
METHOD if_genil_appl_alternative_dsil~save_objects.
DATA lv_cust_key TYPE zattr_cust_key.
FIELD-SYMBOLS <object> TYPE crmt_genil_obj_inst_line.
LOOP AT ct_object_list ASSIGNING <object>.
* Check for Object Instance.
CASE <object>–object_name.
WHEN ‘Customer’.
TRY.
CALL METHOD cl_crm_genil_container_tools=>get_key_from_object_id(
EXPORTING
iv_object_name = <object>–object_name
iv_object_id = <object>–object_id
IMPORTING
es_key = lv_cust_key ).
.
CATCH cx_crm_genil_general_error .
ENDTRY.
* Custom API to Save the customer data.
CALL METHOD zcl_customer_api=>save_customer
CHANGING
cs_key = lv_cust_key.
IF lv_cust_key IS INITIAL.
<object>–success = abap_true.
ENDIF.
ENDCASE.
ENDLOOP.
ENDMETHOD.
Define CS_KEY TYPE ZATTR_CUST_KEY as parameter of Save Customer.
METHOD SAVE_CUSTOMER.
DATA : wa_cust TYPE zmast_cust.
DATA : lv_success TYPE abap_bool.
FIELD-SYMBOLS: <customer_attr_n> LIKE LINE OF gt_customer.
lv_success = ‘X’.
READ TABLE gt_customer ASSIGNING <customer_attr_n> WITH
KEY guid = cs_key–guid
custno = cs_key–custno.
CHECK sy–subrc = 0.
CASE <customer_attr_n>–new.
WHEN ‘C’ OR ‘M’.
MOVE-CORRESPONDING <customer_attr_n> TO wa_cust.
MODIFY zmast_cust FROM wa_cust.
WHEN OTHERS.
ENDCASE.
CALL FUNCTION ‘DEQUEUE_EZMAST_CUST’
EXPORTING
mode_zmast_cust = ‘E’
guid = cs_key–guid
custno = cs_key–custno.
CLEAR cs_key.
ENDMETHOD. “SAVECUSTOMER
Coding Part is Done to create genil implementation class.
STEP 6 : go to transaction genil_bol_browser -> Click on Create a New Root Object
Select the root object as Customer double click it.
Enter the parameters value Custno –
you can add you own custom logic to default set the value of the attributes
Click on Create Object
Here Guid and Custno is in display mode , while remaining atrributes are in changeable mode – Enter the values of the Attributes.
Click on Save Button.
and Check the database table ZMAST_CUST.
In my next blog ‘ http://scn.sap.com/community/crm/webclient-ui-framework/blog/2012/09/25/implementation-of-a-custom-genil-model-in-web-ui ‘ will use this Custom GenIL component set to create a New custom component with create and save the data
in database
Regards,
Sumeet Gehlot
SAP CRM Practice.
Hi Sumeet,
Excellent blog. Can you please update the screen shot of "Component Definition", I would like to know which implementation class you have mentioned there.
Thanks
Imran
Hi Imran ,
Thanks , I have attached a screen shot to register a genil component
Regards,
Sumeet
Quite a few of the images do not show for me... The very first image in the blog is one with a probelm - can you please look into this.
Hi Jason,
Can you please use in mozilla firefox browser.
Unfortunately the company I work for only allows IE! What kind of image or html have you used that won't work with IE? It would be excluding allot of users I think...
(I wish we could run a different browser.)
Can you please show the structure of ZATTR_CUST_TAB. As its not visible if you are already sharing it. The structure of the table doesnt have field like 'NEW'. So do we specifically add 'New' field in struct ZATTR_CUST_TAB.
@Pooja :
I have attached a screen shot of a ZATTR_CUST, Hope it works...
Regards,
Sumeet Gehlot
@Jason : I dont know why images are not visible in IE , hope we can run in different browser.
Regards,
Sumeet Gehlot
Hi Sumeet,
Great Blog and Nice contribution.
Thank u
Das
Hi Sumeet,
can u share the parameter screen shot of Method SAVE_CUSTOMER?
cheers,
Das
Hi Savaridassan,
Create a Parameter as CHANGING type
CS_KEY Changing Type ZATTR_CUST_KEY Customer Key Attribute
Regards,
Sumeet
Hi Sumeet,
Thanks a lot. i worked on this and got the output..sure wil trace and learn a lot.
Thanks again 🙂 expect more resource from u like this...very Good one 🙂
cheers
Savaridassan P
Nice Blog
Hi Sumeet..!
I am new to CRM webui, found the most of the functionality in your article... I tried to impelmented the same thing on my pc and got below errors....
1) In IF_GENIL_APPL_ALTERNATIVE_DSIL~LOCK_OBJECTS
lv_lovk_mode is unknown. it is not contaied in one of the specified table...
2)In class ZCL_CUSTOMER_API.. SAVE_CUSTOMER..
ABAP_BOOL is unknown... when I added the type-POOLs on the top the error is gone..
also in .. GENIL_MODEL_BROWSER when i enter the component as zcust, it never allowed me to create the object when i right click on the root objects it shows collapse Lower-level node and To Higher-level Node.... also in your sample it shows 4 symbols on the top left corner to edit, transport (lorry), refresh and check but it is not showing me on my CRM 7.0 thing..
In my editor it is always a browser... not editor but in your screen shot it is saying as editor.. like GenIL Model Editor: change component... etc
I tried with t-code.. GENIL_MODEL_EDITOR it says it is not found..
When comming to the GENIL_BOL_BROWSER, I eneter the component name it shows empty model browser root objects... I believe this is because I could not create a root object in genil model browser....
Again thnaks for your time in writing such a nice article but i do appreciate it if you clarify my problems.. otherwise it would become an incomplete for me..
Thanks...
Greetings Bala,
anyway Sumeet would be explaining you all in detail...to add with his point..
i too tried this document and got results..
thanks to Sumeet 🙂
the second point u said its ok, i too faced it.
and the document prepared using CRM 7.0 EHP 1 i think so.
in CRM 7.0, you dont have Genil_Model_Editor transcation.
cheers,
Das
Thaks for your info.. atleast I came to know that I am using a different version otherwise I'd have been sitting on it and scratching my head like crazy 🙂 ..
Hi Sumeet Gehlot,
Excellent Blog.
I am new to webclient-ui-framework. I am bit confused of using GUID in tables. Please consider the the simple scenario Company , Department and Employee and try to reply to the thread http://scn.sap.com/thread/3272179 .
Thanks and Regards,
Sumeet S
HI Sumeet,
Excellent blog with complete details.
Just one issue m facing is ... when m trying to create a new root object in Genil_bol_browser with Custno value being 1 ... its giving a dump stating
"
An exception occurred which is explained in detail below.
The exception, which is assigned to class 'CX_CRM_CIC_PARAMETER_ERROR', was not
caught and
therefore caused a runtime error.
The reason for the exception is:
Entry parameter ES_KEY of method CL_CRM_GENIL_CONTAINER_OBJECT->GET_KEY
contains value , which is not allowed
"
can u plzz guide.
Rgds,
Vishal
Hi Sumeet,
Great Blog and Nice contribution.
I am facing problem, when I tried to create a new root object in genil_bol_browser, program generating in short dump with the message
A mandatory parameter was not populated when dyn. calling a method.
Error analysis
An exception occurred that is explained in detail below.
The exception, which is assigned to class 'CX_SY_DYN_CALL_PARAM_MISSING', was
not caught in
procedure "CREATE_HANDLER" "(METHOD)", nor was it propagated by a RAISING
clause.
Since the caller of the procedure could not have anticipated that the
exception would occur, the current program is terminated.
The reason for the exception is:
The mandatory parameter "IV_MODE" of the method "CONSTRUCTOR" of the class
"ZCL_CUSTOMER_MODEL" was not
populated during dynamic method call.
I am using CRM 7.0. I don't understand how to pass "IV_MODE" value. Can any please help me on this?
I could not see the root object in "ZCUST" component or "ZCSET_CUST" component set. No root objects are displaying when I tried to open them. Instead they are displaying in SO2 component/component set.
Hi Sumeet,
have you inherited any class or interface in zcl_customer_api class ?
Thanks,
Hello Reshma,
No Class have been inherited for API class.
Thanks,
Nice Blog.
Hi Sumeet,
I have done all coding and class creation but when i was executing GENIL_BOL_BROWSER its doesn't show any output.please check your yahoo email id i have send attached document.
Hi MRK,
check whether in Get_objects method
zcl_customer_api=>get_customer( EXPORTING is_cust_key = lv_key
IMPORTING es_cust_attr = lv_cust_att ).
Here Lv_cust_attr is getting filled or not .
Try to Debug get_objects and create objects
Regards,
Sumeet
Excellent blog sumeet.
Keep posting....
Regards,
Harish Kumar
Great Article... very helpful.
Good one ... Thanks for sharing.... 🙂
Regards,
Rajesh.
Very interesting and helpful blog.
Good one.Was very helpful
This blog is for who are new to crm technical and wants to know basic about genil bol programming.
Very useful blog.
If possible can u pls tell me how to create Orders programatically in CRM.
Pls Help me i am new to crm.
Very useful blog....
Thanks for sharing
Great blog, thanks a lot!
Hi,
Nice documentation for CRM beginners,
I have one doubt though,
When Iam tring to execute GENIL_BOL_BROWSER,after creating a new object,when Iam clicking on save,only GUID and CUSTNO are getting saved,no other field like CUSTNAME etc is getting saved in the database.
Please advise on the rectification of this issue.
Can you put a break point IF_GENIL_APPL_ALTERNATIVE_DSIL~SAVE_OBJECTS in this method a and see whether before modify statement table is filled with values.
It worked for me, Thanks.I had not checked the initialization of iv_root_list in modify object. So the entire method was getting completely overlooked.
Hi,
I have done all the steps as mention in above document, also added the code inDO_INIT_CONTEXT and other EH_ONCREATE and EH_ONSAVE, but when I ma testing it system is giving the UI screen with message as below.
CUSTNAMEnot bound
TELEPHONEnot bound
CITYnot bound
etc.
Regards,
Zafar
Very useful!
Hi Sumeet,
I am new in CRM Web UI.
But i can start and understand Genil model from your blog.
Very good blog.
Thank you very much indeed.
Regards,
Hiranya
Thanks for the effort !
Hi Gowtham,
Did you pass rv_success of the genil class as true?