Help Needed: Issue with CUSTOM WEB SERVICE for Deleting Lead
Hello Community,
I’m working on creating a custom web service to delete a lead record, but I’ve run into an issue that I can’t seem to resolve. Whenever I attempt to delete a lead using its ContactId
, I receive the following error:
"Error occurred while deleting: Item cannot be deleted because it is being used in a process."
Here’s what I’ve tried so far:
- Removing the Process Connection:
The lead is connected to a business process (Lead Processing
) through a "Connect process to object process element." I attempted to remove this connection from the base process, but doing so broke other functionalities that are dependent on this process. - Calling the Process Cancel Execution Service:
I attempted to call theCancelExecution
service (ProcessEngineService.svc/CancelExecution
) to cancel the execution of the process. However, this service requiresprocessDataIds
in the body, which I cannot retrieve within the delete contact web service. - Deleting the Connected Record:
I explored deleting the record connecting the process to the lead, but I couldn’t locate the object holding this connection.
Below is the source code for my delete operation. The logic works perfectly when I stop the "Lead Processing" business process, but that’s not a sustainable solution.
Source Code: using System; using System.ServiceModel; using System.ServiceModel.Web; using System.ServiceModel.Activation; using Terrasoft.Core; using Terrasoft.Web.Common; using Terrasoft.Core.Entities; using System.Collections.Generic; namespace Terrasoft.Configuration.UsrDeleteLeadNamespace { [ServiceContract] [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)] public class UsrDeleteLead : BaseService { [OperationContract] [WebInvoke(Method = "DELETE", RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)] public string DeleteLead(string LeadId) { if (!Guid.TryParse(LeadId, out Guid parsedLeadId)) { return "Invalid Lead ID format or Lead doesn't exist."; } UserConnection userConnection = GetUserConnection(); EntitySchemaManager entitySchemaManager = userConnection.EntitySchemaManager; try { // First check and delete connected Lead Products EntitySchema leadProductSchema = entitySchemaManager.GetInstanceByName("LeadProduct"); var leadProductEsq = new EntitySchemaQuery(leadProductSchema); leadProductEsq.AddAllSchemaColumns(); leadProductEsq.Filters.Add(leadProductEsq.CreateFilterWithParameters(FilterComparisonType.Equal, "Lead", parsedLeadId)); var leadProductCollection = leadProductEsq.GetEntityCollection(userConnection); // Manually convert EntityCollection to a List var leadProductCollectionToDelete = new List<Entity>(); foreach (var leadProductEntity in leadProductCollection) { leadProductCollectionToDelete.Add(leadProductEntity); } // Delete the Lead Products foreach (var leadProductEntity in leadProductCollectionToDelete) { leadProductEntity.Delete(); } // First check and delete connected Activity EntitySchema activitySchema = entitySchemaManager.GetInstanceByName("Activity"); var activityEsq = new EntitySchemaQuery(activitySchema); activityEsq.AddAllSchemaColumns(); activityEsq.Filters.Add(activityEsq.CreateFilterWithParameters(FilterComparisonType.Equal, "Lead", parsedLeadId)); var activityCollection = activityEsq.GetEntityCollection(userConnection); // Manually convert EntityCollection to a List var activityCollectionToDelete = new List<Entity>(); foreach (var activityEntity in activityCollection) { activityCollectionToDelete.Add(activityEntity); } // Delete the Lead Products foreach (var activityEntity in activityCollectionToDelete) { activityEntity.Delete(); } // Now check and delete the Lead EntitySchema leadSchema = entitySchemaManager.GetInstanceByName("Lead"); Entity leadEntity = leadSchema.CreateEntity(userConnection); if (!leadEntity.FetchFromDB("Id", parsedLeadId)) { return "Lead not found."; } if (leadEntity.Delete()) { return $"Lead and {leadProductCollection.Count} related product(s) have been deleted successfully."; } else { return "Failed to delete Lead."; } } catch (Exception ex) { return $"Error occurred while deleting: {ex.Message}"; } } } }
I would greatly appreciate any suggestions or guidance on how to resolve this issue. Specifically:
- Is there a way to identify and cancel the process dynamically before deleting the lead?
- Can I identify and delete the connecting record that prevents the deletion?
- Are there alternative approaches I should consider?
Like
Hello,
Thank you for the detailed explanation of the task.
You can reproduce this behavior through the UI by creating a new lead record and then trying to delete it - you get a message about related records, as shown in the screenshot.
In this case, blocking the deletion of the record occurs due to the running business process “Lead processing”, which creates an activity on the lead and, accordingly, an instance of the process.
According to your code, we see that you are already deleting the activities associated with this lead, so you just need to cancel the business process instance.
To implement this, the ProcessEngineService.svc/CancelExecution endpoint can be a good fit, where you need to pass the business process instance ID in the request body:
{“processDataIds”:“045ea1bc-f366-4837-994f-d229fc8a91d4”}
So, the question remains as to where you can find the instance ID of the business process that uses this record.
The “SysProcessEntity” table stores data about the relationship of the record with the business process instance. The important columns for you are:
1) EntityId - the identifier of the linked record. That is, in your case, the record ID of the lead to be deleted
2) SysProcessId - the identifier of the process instance that is associated with this record.
3) EntityDisplayValue - the value from the Display Value column for the Lead object. By default, this is the “LeadName” column.
Before calling the ProcessEngineService.svc/CancelExecution endpoint with the process ID, you can also check the business process name in the SysProcessLog table (Id = {id from SysProcessid column}).
Thank you.