02-01-2013 03:04 AM
Hello everyone,
Recently I encountered a problem during programming a plugin for one of our customers. The plugin should have quite simple functionality - it should react when user changes process in opportunity and when he/she chooses a particular process, plugin should change the opportunity status to "Won". I registered CurrentOpportunityChanged event handler and inside it - FieldChanged event handler (for current opportunity fields. The code runs quite smooth but there is one problem - when event handler is registered in such a way, the event fires many times (I made a counter, one change of opportunity process makes the event fire 7-24 times). If an user changes current opportunity and navigates back, number of firing doubles, then triples and so on. I tried to stop the event cascade by creating a Dictionary<Guid, int> and saving opportunities guids there in order to prevent event from adding to event sink but it sometimes causes the event stop firing at all. I tried so hard to understand connections between various ACT! events but finally I gave up.
My code here:
void ActApp_CurrentOpportunityChanged(object sender, EventArgs e) { IOpportunityDetailView view = ActApp.CurrentView as IOpportunityDetailView; if (view != null) BlockOpportunityFields(view); var curr = ActApp.ApplicationState.CurrentOpportunity; curr.Fields.FieldChanged += new MutableEntity.FieldCollection.FieldChangedHandler(Fields_FieldChanged); //if(!_oppChangedEventHandlerAdded.ContainsKey(ActApp.ApplicationState.CurrentOpportunity.ID)) //{ // curr.Fields.FieldChanged += new MutableEntity.FieldCollection.FieldChangedHandler(Fields_FieldChanged); // _oppChangedEventHandlerAdded.Add(ActApp.ApplicationState.CurrentOpportunity.ID, 1); //} } //_oppChangedEventHandlerAdded - this is my dictionary void Fields_FieldChanged(string fieldName) { if(fieldName.Contains("TBL_OPPORTUNITY.STAGEID")) { _eventCounter++; var curr = ActApp.ApplicationState.CurrentOpportunity; var stageFieldId = curr.Stage.ID; if(stageFieldId != null) { var processName = SQLManager.GetProcessName(stageFieldId.ToString()); if(processName == "4. Sprzedaż") { curr.Status = OpportunityStatus.Won; //SQLManager.UpdateOppStatus(curr.ID); } } } } //SQL Manager is my static class that handles LINQ operations on ACT! database
Any help with this matter would be appreciated.
11-18-2014 06:52 AM
Did you ever have any luck with this? I have the same problem.
11-18-2014 07:11 AM
I seems like I can change any field on the opportunity except the status field and when I click Save the OpportunityChanging and OpportunityChanged event will fire.
As soon as I change the Status field the FieldChangeEvent will fire once as I am only capturing field change for the status field. And then the OpportunityChanging and OpportunityChanged events will fire close to 5 times.
// in the AfterLogon event I register for the CurrentViewChanged event private void actApp_CurrentViewChanged(object sender, EventArgs e) { IOpportunityDetailView view = actApp.CurrentView as IOpportunityDetailView; if (view != null) { this.actApp.CurrentOpportunityChanged += actApp_CurrentOpportunityChanged; this.actApp.CurrentOpportunityChanging += actApp_CurrentOpportunityChanging; } else { this.actApp.ApplicationState.CurrentOpportunity.Fields.FieldChanged
-= Fields_FieldChanged; this.actApp.CurrentOpportunityChanged -= actApp_CurrentOpportunityChanged; this.actApp.CurrentOpportunityChanging -= actApp_CurrentOpportunityChanging; } } private void actApp_CurrentOpportunityChanged(object sender, EventArgs e) { MessageBox.Show("Opp Changed"); actApp.ApplicationState.CurrentOpportunity.Fields.FieldChanged += new MutableEntity.FieldCollection.FieldChangedHandler(Fields_FieldChanged); } private void actApp_CurrentOpportunityChanging(object sender, EventArgs e) { MessageBox.Show("Changing Opportunity"); actApp.ApplicationState.CurrentOpportunity.Fields.FieldChanged -= new MutableEntity.FieldCollection.FieldChangedHandler(Fields_FieldChanged); } private void Fields_FieldChanged(string fieldName) { if (fieldName.Contains("TBL_OPPORTUNITY.STATUSNUM")) { MessageBox.Show("Fired"); Opportunity opp = actApp.ApplicationState.CurrentOpportunity; MessageBox.Show(opp.Status.ToString()); } }
Any thoughts on this. Am I doing something out of order?
11-18-2014 08:16 AM
I haven't played with the Opportunity View change event but if it is doing what you say it is doing I would save the current view and if the new view was the same as the current view I would handle it appropriately. It sounds like the Opportunity View can change to the Opportunity View which you would think technically shouldn't be able to happen.
Stan
11-18-2014 08:28 AM
Ok thanks very much for your suggestions I'll try that out and let you know if it makes any difference.
I'll also try not using View Changed event also and see if that makes any difference at all.
Thanks again.
-Eric