cancel
Showing results for 
Search instead for 
Did you mean: 

Need help to get deleted product info at runtime in PDI

0 Kudos

Hello Colleague,

In C4C my requirement is whenever any item is deleted(i.e delete action clicked) in Sales Quote, I need to get the hold of the product that is deleted and update some attribute in the product.

The problem I am facing is once the item is deleted in UI how I will get the information of deleted line item in PDI at runtime so that I can write the business logic.

There is no after delete event in the script files , neither event After Modify  at Item node is getting called .Moreover when I tried to re-read the same Quote by query api and compare that with the "this" instance it has same number of products i.e the deleted line item  is not there .

Any one who can help me in this.

With Regards,

Saurabh Kumar Pandey

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Hello.

1) You can use the after modify event but not at root node: you need to use the one at item node.

2) You need to query the sales quote. Probably you are using the retrieve method. With the retrieve data are loaded from the local instances, if existing.

0 Kudos

Hi Alessandro ,

Thanks for your reply .

1. I used the after modify event in Item node . The control comes here when the product is added but not when deleted.

2. I am not using retrive . I am using the query mentioned below in before save event in Root. But data retruned in the same as "this" instance.

qry = CustomerQuote.QueryByElements;

param = qry.CreateSelectionParams();

param.Add(qry.ID.content,"I","EQ",this.ID.content);

result = qry.Execute(param);

quote = result.GetFirst();

With regards,

Saurabh Kumar Pandey

Former Member
0 Kudos

Can you try checking the Item.ItemProduct node?

Same for the aftermodify event: ItemProduct.node->AfterModify

HorstSchaude
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hello Alessandro,

If the Item node is deleted, all dependent nodes i.e. the instances of the ItemProduct node are also deleted.

Therefore I do not think this makes sense.

As we do not have access to the BeforeImage in PDI I suggest the following:

  • Each time a Item is added create a node in a "shadow BO" which contains information about the product which is used
  • In the BeforeSave event of the SalesQuote check what Items do exist now and whicha re in the shadow BO.
    From there you know which Products to update

HTH,

   Horst

Former Member
0 Kudos

Yes this is a solution.

But I don't understand why by querying the Sales Quote BO the deleted items are not in place. They should be there because the save action is not raised when you delete an item, so the persistent data sould not change.

The aftermodify at itemproduct.node can be useful to intercept the delete action that is not raising the aftermodify event at item level. Maybe?

0 Kudos

Hi Horst ,

Thanks for your reply . Can you help me how to cerate the shadow BO and keep the instance alive throughout the transaction .

With Regards,

Saurabh Kumar Pandey.

0 Kudos

Hi Alessandro ,

I implemented the Itemproduct node AfterModify method and the control didn't came to this method when the item was deleted . However when the item is getting added the method is getting called.

With Regards,

Saurabh Kumar Pandey

Former Member
0 Kudos

So if by doing a query you are retrieving the same data that you have in the current session (this is a bug anyway because query should get persistence data, you should raise an incident for this), this mean that query have some problem retrieving the same object on wich you are working on (you are inside a sales quote => you can't do a query on the sales quote). I had a similar issue with the activity.

To avoid this beaviour you can create a simple webservice based on a custom bo that performs a query and return the persistance collection of items. This will work because the ws call is performed in another session.

0 Kudos

Hi Alessandro ,

Thanks for the alternative solution . Meanwhile for my Quote Line item case I am suggesting the pre-sales team to use the rejection reason to reject an item instead of deleting the line item .

I will update the business logic based on that .

But I see gaps in PDI framework incompare to CRM UI crud services . Hope this GAP are addressed in new releases.

With regards,

Saurabh Kumar Pandey

HorstSchaude
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hello Alessandro,

The docu for Queries says:

Execute Function

The Execute function of a query returns a collection of
instances of the node to which the query is bound. Queries can be executed
directly with no further parameters specified. Usually, you provide selection
parameters to narrow down the result set as much as possible to the desired node
instances by defining appropriate filtering criteria. The instances returned by
the Execute function overwrites any unsaved changes
performed by script files before calling Execute.

The bold sentence explain that any data in the BO buffer modified in "countless UI loops" and "manifold ABSL snippets" by the data from the persistence.

BTW: I've had to read by myself to make myself familar with this behaviour

HTH,

    Horst

Former Member
0 Kudos

Thanks Horst,

is that an available document? Where did you find it?

HorstSchaude
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hello Alessandro,

Docu for 1408,

Section 7.2.4.31

Should be on top of page 218

HTH,

  Horst

HorstSchaude
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hello Saurabh,

  • First define a new Custom BO (the shadow BO) which contains all information you need later.I assume this would be the SalesQuoteID as an AlternativeKey and in a multiple subnode the SalesQuoteItemID and the ProductID (or the ProductKey).
  • Expand the SalesQuoteItem node with a element whioch tells you if the shadow BO is already created, say

          element ShadowBOCreated : Indicator;

  • Add a AfterModify method to the SalesQuoteItem node which checks this indicator.
    • If it is not set it first tries to retrieve the shadow BO by the SalesQUoteID.
    • If nothing is found it creates this instance (the Root node)
    • Next it tries to access the subnode of the shadow BO with the SalesQuoteItemID
    • If nothing is found it creates this subnode
    • Finally it ensures that the ProductID of the SalesQuoteItem is the same as in the subnode of the shadow BO
  • Add a BeforeSave method to the SalesQuote (Root node)
    • The resp. shadow BO instance is retrieved
    • For every subnode of this shadow BO it is checked if the corresponding SalesQuoteItem exists.
    • If not the resp. Item node was deleted and in the subnode you still have the Product ID
    • You do what you need to do
    • The subnode of the shadow BO is now also deleted

That's all folks. [Porky]

HTH,

   Horst


Former Member
0 Kudos

Hi Horst.

Are you sure this works correctly?

How do you handle the case if only the SalesQuoteItem is deleted and nothing else?

From my understanding one does not get a BeforeSave event on the root node if the root node has not been modified. instead the BeforeSave happens on the subnode modified.

Since there is no (other than the deleted) node modified the BeforeSave is not triggered.

At least this was the situation with custom BOs when we faced the same problem.

Since this was a custom BO we could handle this case ourself though: by calling a custom action that did the update and then performs the deleting.

Or is this different for XBOs?

Best regards,

Ludger

HorstSchaude
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hello Ludger,

Good point.

So the BeforeSave coding should be attaced to the tem node.

Be,

   Horst


Former Member
0 Kudos

Hi Horst,

unfortunately (as I wrote earlier) deletion does not trigger a BeforeSave since a deleted Node is not saved.

So there is no way receive an envent to detect deleted objects using the existing events on the object itself.

My approach would therefore be different:

1. Create an asynchronous communication synchronizing between the original object and the custom object creating a copy of the product id as well as copying the alternative key or UUID. Configure the Communication such that a delete of the source object does not trigger a delete of the destination object.

2. In the BeforeSave of the custom Object, check (using the alterative key/UUID) whether the original object does exist. If no:

2a., it has been deleted => Call Custom action (you have the product id synchronized

2b. delete the custom object instance afterwards to clean up 😉

This should solve Saurabhs problem.

Best regards,

Ludger

HorstSchaude
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hello Ludger,

Hm, I wonder if the work Saurabh wants to do is performed and persisted if the item is created and deleted in the same sesssion.

I would expect that a check should run on save verifying if the item is still existing.

Bye,

    Horst

Answers (1)

Answers (1)

0 Kudos

Hello Colleagues ,

Thanks for the helpful answers . I was on Vacation so couldn'r reply to this thread . I did a workaround wherein I requested the tester not to delte an item from the quote but to set the Rejection reason status . And this works for me .

None the less I will keep in mind of the other helpful answers I have received.

With Regards,

Saurabh Kumar Pandey