Skip to Content
Author's profile photo Alessandro Iannacci

Cloud for Customer – How to bind EC to a standard screen without using context binding or outports

Probably you know that, in order to pass parameters from a screen to an embedded component, you need to bind your EC context to the main component context, or you need to use an outport containing one or more parameters, from the main component to the EC.

If you are working with a completely custom main component, these kinds of binding are possible, but try to imagine the situation in wich the main component is a standard screen (for example the QC component of an ActivityTask).

This standard component have no outports, and cause it is a standard screen you are not able to bind the EC context with the main component context.

So… have you to give up?

Look at the following procedure, proposed by me, and already approved by SAP Cloud for Customer Development Team!

_________________________________________________________________________________________

Requirement: create an embedded component that can take the existing instance of an object without the need of context mapping and outport parameters.

Idea: when the object (in this example a task) is created or modified, we want to save the instance UUID (that it is not already saved in the persistence layer) in a custom business object, without the need to save it, and then, using the retrieve function as a transformation field in the embedded component (EC), we get the task UUID and we read the existing instance using the retrieve function.

     

Limits:

  • A UI can have only one Business Object mapped on the context.
  • A query cannot be used because we can’t save the custom instances.
  • It is not possible to save an identifier in a custom field of the task in order to get the BO with a retrieve in the UI because the retrieve doesn’t support custom fields.
  • It is not possible to duplicate the standard screen in the embedded component by creating a new instance in the EC and deleting the original instance, because some event handler of the main component work on the original instance (i.e. save and complete).

  

Useful informations:

/wp-content/uploads/2013/11/usf_332820.png

Getting started!

Step 1.

Create a business object extension for the ActivityTask standard BO with a dummy field (almost a field is required).

/wp-content/uploads/2013/11/1_332821.png

Step 2.

Implement the Event-AfterModify.absl in order to save the task UUID by using a reuse function called WRITE_TASK (to be created in the step 4).

/wp-content/uploads/2013/11/2_332879.png

Step 3.

Create a custom BO that will handle the association USERUUID (unique key) to TASKUUID.

/wp-content/uploads/2013/11/3_332880.png

Step 4.

Create the Reuse Library with two functions: READ_TASK and WRITE_TASK.

/wp-content/uploads/2013/11/4_1_332881.png

/wp-content/uploads/2013/11/4_2_332885.png

The WRITE_TASK function check for existing instances with the key userUUID equal to the current userUUID. If the instance exists, it will update the taskUUID with the importing parameter, otherwise it will create a new instance.

/wp-content/uploads/2013/11/4_3_332886.png

The READ_TASK function check for existing instances with the key userUUID equal to the current userUUID. If the instance exists it return the associated taskUUID.

/wp-content/uploads/2013/11/4_4_332887.png

Step 5.

Create the Embedded Component with an hidden field TaskUUID binded with the /Root/DataField context node.

/wp-content/uploads/2013/11/5_1_332891.png

You can also add some other fields binded to the context attributes related to the task (see next step). In this example I added task name and task category.

/wp-content/uploads/2013/11/5_2_332892.png

/wp-content/uploads/2013/11/5_3_332893.png

Step 6.

Bind the Root note to the ActivityTask standard BO and add some fields if you want (see step 5). No initialize event handler is required.

/wp-content/uploads/2013/11/6_332894.png

Step 7.

Add a new field DataField to the context and set property “Is Dedicated Field” to TRUE (1).

Select a new Transformation Field and choose the READ_TASK function from the custom reuse library (see step 4) (2).

Add an event handler to the event OnValueChanged of this field (3).

Bind the Root element (4).

/wp-content/uploads/2013/11/7_332895.png

Step 8.

Check the created Field Transformation (automatically generated).

/wp-content/uploads/2013/11/8_332896.png

Step 9.

Create the BOOperation for the event handler using the read (retrieve) operation and add the NavKey parameter as nodeId, binded with the DataField (that will contain the taskUUID).

So when the EC is initialized, the field transformation start, the task UUID is filled, andthe event handler is loaded because of the DataField modification.

/wp-content/uploads/2013/11/9_1_332900.png

Step 10.

Add the EC to the standard QC component (no bindings are required).

/wp-content/uploads/2013/11/10_332901.png

Step 11.

You are ready to test!

Open a new task and check that the EC has the same values of the standard component. Try to change some value (and press enter because standard fields have no event handler associated) in order to see the new values also in the EC.

/wp-content/uploads/2013/11/11_332902.png

If you want that, by changing the category dropdown, the dependant dropdown automatically changes (withouth the need to press the enter), you have to hide the standard field and let the user to use the replicated field in the EC.

Assigned tags

      42 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Jens Limbach
      Jens Limbach

      Hey Alessandro!

      Thanks for the great tutorial! This is really great as this way we don't have to have an outport 🙂

      Really helpfull! In general it would be greate to know more about how to reuse libaries in combination with the UI via transformation. I think it is quite cool 🙂

      Cheers,
      Jens

      Author's profile photo Alessandro Iannacci
      Alessandro Iannacci
      Blog Post Author

      Hi Jens,

      thank you! I hope that this blog will be useful.

      Author's profile photo Former Member
      Former Member

      HI Alessandro,

      Thanks for the useful information regarding the EC and it was described excellently..

      Regards..
      Hanumath K

      Author's profile photo Former Member
      Former Member

      Hi Alessandro,

      thanks for the info, it's interesting regarding EC.

      Regards,

      Joe.

      Author's profile photo Gayathri Ramachandran
      Gayathri Ramachandran

      Hi Alessandro,

      I have something similar requirement. Here you have discussed about outport but mine is on inport.

      My requirement is with Activity BO's QC. Where in I need to pass the ID from the Custom BO to the QC screen. Since the inport is missing I  have difficult in doing this.

      Is there any suggestions you have.

      Author's profile photo Vinodkumar Kommineni
      Vinodkumar Kommineni

      Hi Alessandro,

      Excellent Blog! Hope to see more blogs from you.

      Regards

      Vinod

      Author's profile photo Alessandro Iannacci
      Alessandro Iannacci
      Blog Post Author

      Thank you Vinod

      Author's profile photo Former Member
      Former Member

      Good Blog! Appreciate your time spent on this 🙂

      Author's profile photo Mani B
      Mani B

      Nice Blog.

      it saved my time..:).Appreciate your time spent on this blog.!

      Author's profile photo Mani B
      Mani B

      Hi Allesandro ,

      In the new Actiivity BO of 1402 , SAP seems to be included the UUID type from namespace Common.DataTypes but in the 1311 its from Ap.Common.GDT , So now when i write the task UUID in step 2 its giving me error..since the this.UUID is from Common.datTypes but the importing parameter(UUID) of Write_task method is from AP.Common.GDT, How to resolve or change the above scenario as per the new changes in Activity BO??

      I tried to use the UUID namesspace in the reuse library to Common.DataTypes but in the USERUUID Bo , if i change the namespace to Common.Datatypes then its not allowing me to add the promary key in the bo, Could you please let me know the possible solution for this issues??

      Thanks,

      Mani

      Author's profile photo Alessandro Iannacci
      Alessandro Iannacci
      Blog Post Author

      Why is not allowing you to add the primary key in the BO?

      Use the correct namespace you should not have problems.

      Post an error screenshot

      Author's profile photo Mani B
      Mani B

      I did a small mistake..Now its resolved..!! In the custom BO UserUUID i took it from AP.Common.GDT and TaskUUID i took it from Common.DataTypes namesspace.

      Now its working fine..:)

      Thanks,

      Mani

      Author's profile photo Fred K
      Fred K

      Hi, Alessandro,

      This is really great. This works perfectly when creating a new account.

      But doesn't work when editing an existing account.

      Is it because of my mistake?

      Regards,

      May T.

      Author's profile photo Alessandro Iannacci
      Alessandro Iannacci
      Blog Post Author

      Hi, it should work, but it is better to use the normal approach using the standard outport.

      Author's profile photo Fred K
      Fred K

      HI, Alessandro,

           Great post. Really helpful.

           Have two questions?

           1. When I edit, the aftermodify is not working, so that the standard BO is not unable to      create an instance of Custom BO. How should I do about this?

           2.What if the same user create more than one accounts at the same time?

           How can I control that?

      Please give your advice on those two above. 

      Regards,

      May T.

      Author's profile photo Alessandro Iannacci
      Alessandro Iannacci
      Blog Post Author

      Hi Fred,

      for the point 1 there is not solution. Maybe you can try to trigger the after modify with some dummy automatic operations made with another embedded component.

      For the point 2: what do you mean creating more than one account at the same time? With the UI you can only create one object at time, can you make an example?

      Author's profile photo Fred K
      Fred K

      Hi, Alessandro.

           For point 2, what I meant is "creating more than one account at the same time with two windows or taps by the same user". Not a quick create though. I am using your idea on ByD where I can open more than one tap at the same time.

      Regards,

      Fred

      Author's profile photo Alessandro Iannacci
      Alessandro Iannacci
      Blog Post Author

      This is not a problem you just need to add as key for the custom BO, the concatenation of user uuid and account id instead using only the user uuid.

      Author's profile photo Fred K
      Fred K

      Hi, Alessandro,

           So, you mean I should concatenate the UserUUID and AccountID.

           So, how can I retrieve the instance?

           Doesn't that retrieve method works on UUID?

        Regards,

      Fred

      Author's profile photo Alessandro Iannacci
      Alessandro Iannacci
      Blog Post Author

      Use two fields:

      UserUUID+accountUUID (key) | AccountUUID

      Author's profile photo Fred K
      Fred K

      Hi, Alessandro.

           What you mean is creating a new UUID from the sum of UserUUID and AccountUUID. 🙂

      Regards,

      Fred

      PS. sorry for my stupidity. 🙂

      Author's profile photo Alessandro Iannacci
      Alessandro Iannacci
      Blog Post Author

      Don't worry you can ask everything!

      Exactly, creating a new alternativekey made by sym if UserUUID and AccountUUID, in this way also if you create two Account at the same time you should not have problems!

      Author's profile photo Fred K
      Fred K

      Thank you so much , Alessandro

      Looking forward to your next posts.

      Regards,

      Fred

      Author's profile photo Former Member
      Former Member

      Hi Alessandro,

      I can't understand your approach for solving the point 2 of Fred. Are you going kind of encrypt an AccountUUID along with UserUUID and then decrypt it (in the READ_TASK function), am I right?

      It is somehow mysterious for me, because at that phase (in the READ_TASK) the AccountUUID is unknown. The AccountUUID is actually the parameter which has to be handed over! So as far as you don't know the AccountUUID you can't compose the sum of the AccountUUID and UserUUID in order to Retrieve the USER_TO_TASK Object.

      Best regards,

      Leonid Granatstein

      Author's profile photo Former Member
      Former Member

      Hi Fred,

      I didn't test this particular app but from my experience opening an UI in the new tab creates a new session. Datas in the buffer memory which are accessed by the Retrieve function are incapsulated, t.i. there are actually one buffer pro session. So from my point of view you won't need an additional key like account uuid.

      Moreover, I don't actually see the necessaty to use the User UUID, for the same reason. Alessandro, have you evaluated to come out with a singleton here? It seems to me that you just have to add a BeforeSave action to the Task, where you delete the created singleton to avoid the locking problems.

      Regards,

      Leonid.

      Author's profile photo Former Member
      Former Member

      Hi,

      I've tested my proposal to use the Singleton Object, and it works fine.

      Also this works for the case when one user tries to create different tasks at once.

      Merely the idea to delete the singleton object in the BeforeSave event  didn't worked out. It's kind of stange, because it is true that all buffers in memory are incapsulated within the session, so the Retrieve from the different Tab or different user delivers no results. The Create is not possible, though. That is not like on the picture "Useful Information" provided by Alessandro.

      So I'd to use some other trick to prevent concurrency in the DB, a little bit more complex but also not larger than a couple of script lines.

      Leonid

      Author's profile photo Tom Lennart Behrens
      Tom Lennart Behrens

      Hello Allessandro,

      Horst Schaude mentioned, that your approach might also help me with my requirement. Hence you use the RETRIEVE, which is based on the ID, I am not quite sure, if it really could help me on my requirement (embedding a subset of Opportunities into a Custom-BO Screen).

      Could you kindly have a look at my posted question?

      http://scn.sap.com/thread/3588006

      Thanks in advance and best regards

      Tom

      Author's profile photo debasis mohapatra
      debasis mohapatra

      HI Alessandro,


      Thanks for this nice blog, But i have  one more question . Is there any way that instead of putting that EC at the end we can able to place it somewhere in between at a specified place according to the requirement ..



      thanks

      Debasis


      Author's profile photo Alessandro Iannacci
      Alessandro Iannacci
      Blog Post Author

      Unfortunately not 🙁 You can place ECs only where you have the standard anchors

      Author's profile photo debasis mohapatra
      debasis mohapatra

      Thank you .for the response ..

      As expected ...

      Author's profile photo Jacques-Antoine Ollier
      Jacques-Antoine Ollier

      Hello Alessandro,

      I am trying to do something similar to your model, but I am facing an issue with the custom functions.

      When I try to Retrieve an instance of my custom BO in the WRITE.absl, all my fields are read-only. I cannot change their values.

      The weird thing is these custom fields can be modified from other script files:

      - in before-save of an .xbo. with a Retrieve on my custom BO,

      - in the After-Modify of this custom BO,

      - but all my custom fields are read-only in the function WRITE.absl...

      Do you have any clue on this?

      Thank you very much for your attention.

      Best regards.

      Jacques-Antoine

      Author's profile photo Alessandro Iannacci
      Alessandro Iannacci
      Blog Post Author

      hi, check the deployment unit for the reuse function

      Author's profile photo Alessandro Iannacci
      Alessandro Iannacci
      Blog Post Author

      Another thing: check that the reuse function is write enabled

      Author's profile photo Pablo Hernández Martínez
      Pablo Hernández Martínez

      Hi Alessandro,

      I realized all steps with this tutorial, but for my project it doesn't work very well...

      At step 10 I would like to Add the EC to the standard ODT_ExpenseReport_HTML_EC.EC.xuicomponent but i don't find my custom EC.

      EC1.jpg

      I tried also with others floorplans but didn't find too.

      Could you tell me any advise?

      Thanks,

      Author's profile photo Alessandro Iannacci
      Alessandro Iannacci
      Blog Post Author

      From your screenshot i see two pane containers. Try the second one.

      Author's profile photo Pablo Hernández Martínez
      Pablo Hernández Martínez

      There are 3, but all of them don't show any EC...

      Author's profile photo Alessandro Iannacci
      Alessandro Iannacci
      Blog Post Author

      In this case better to raise an incident. Maybe there is some problem with the standard anchor

      Author's profile photo Former Member
      Former Member

      Hi,

      I've implemented this tutorial and I've seen that some steps need clarification or correction. This is mostly because of the changes since the older releases of the Studio.

      I've used C4C 1511. I've writen down the details on how I adopted the solution provided by Alessandro. The following applies:

      0.

      The solution has to be preferrably in the Foundation deployment unit.

      the deployment unit of the BO USER_TO_TAK has to be "Foundation", otherwise it is not possible for the function "WRITE_TASK" from the CUSTOMER_REUSE library to write into this BO

      The easy way to achieve this is to create the solution in the foundation deployment unit

      On the Step 1.

      The BO ActivityTask from the namespace AP.FO.Activity is deprecated, you have to take the BO Activity from the namespace AP.PC.ActivityManagement.Global instead

      Dummy field in the activity extension isn't required any more, the extension is possible without elements

      On the Step 4.

      The parameters UUID in the Reuse library "CUSTOMER_REUSE" for both functions "READ_TASK" and "WRITE_TASK" should  be not of type "AP.Common.GDT" but of the type "Common.DataTypes" to be compatible to the UUID of the BO activity; the same goes for the element "taskUUID" in the VO USER_TO_TASK

      On the Step 6.

      Instead of the element Activity.Name for the EC field you can take Activity.SubjectName

      On the Step 7.

      You don't have to add the DataField to the context since it has already been added in the Step 5.

      Best regards,

      Leonid

      Author's profile photo Alessandro Iannacci
      Alessandro Iannacci
      Blog Post Author

      thank you leonid. It is true this blog was referring to the old 1311 version and many things changed in the meanwhile

      Author's profile photo s sin
      s sin

      Hello,

      I am on 1605, I just wanted to say that for me all the data types that are related to UUID sshould be "AP.Common.GDT", so is not necessary to change them.

      As you said I create my custom BO in Foundation deployment unit.


      Like below:


      [DeploymentUnit(Foundation)]  businessobject Custom.BO {


      ....


      }


      Regards,

      Sin

      Author's profile photo s sin
      s sin

      Thanks Alessandro,

      Very useful!

      Author's profile photo Former Member
      Former Member

      Dear Alessandro,

      thank you very much for the tutorial. It is extremely helpful to know that binding of an embedded component can work without inport/outport parameter configuration and their binding.

      The only issue I have is the WRITE UUID function, because it doesn´t update the UUID of an existing instance. I tried your approach for the Customer BO. After the first instantiation of the UUID with the same user uuid, I am not able to update the value and therefore the first created instance always appears in the embedded component. I also debugged the Code, I can see that the new value of UUID is written into the datafield but with no persistence. Maybe you know something that could support me with my issue.

      Example:

      instance = CustomDummy.Retrieve(Context.GetCurrentIdentityUUID());
      if (instance.IsSet()){
      instance.CustomerUUID = CUSTOMER_UUID; ---->it doesn´t update the value

      Best regards,
      Rufat