Weird BPM Behavior

I have a Pre-Processing BPM for Labor.Update which is acting a bit odd. I have posted the full code below for reference. You will notice that there are 9 InfoMessage.Publish("#"); and 1 ‘if’ statement (nearer to the bottom, after InfoMessage.Publish(“8”)

InfoMessage.Publish("1"); // First thing that should happen when this fires is this box appearing
Erp.Tables.JobOper JobOper; // Need to be sure this is available to us
InfoMessage.Publish("2"); // Now show this box
tooMany = false; // default this to False, just in case it stuck around for some reason

//prevOpQtyComplete = 0;
//thisOpQtyComplete = 0;
//totalQtyComplete = 0;

var ttLDtl = ttLaborDtl.Where(x => x.RowMod != "").FirstOrDefault(); // Lets get this transaction info

InfoMessage.Publish("3");  // Now I should see this box

// This seems to work as expected, allowing me to use JobOper in the next few sections    
JobOper = (from JobOper_Row in Db.JobOper 
                                          where JobOper_Row.Company == Session.CompanyID 
                                          && JobOper_Row.JobNum == ttLDtl.JobNum
                                          && JobOper_Row.OprSeq <= ttLDtl.OprSeq
                                          select JobOper_Row).FirstOrDefault();



InfoMessage.Publish("4"); // Followed by this one                                

// This correctly sets the prevOpQtyComplete to the Qty Complete in the previous op                                          
prevOpQtyComplete = (from JobOper_Row in Db.JobOper where JobOper_Row.JobNum == ttLDtl.JobNum
                                          && JobOper_Row.OprSeq < ((from JobOper_Row0 in Db.JobOper where JobOper_Row0.JobNum == ttLDtl.JobNum
                                          orderby JobOper_Row0.OprSeq descending select new {
                                              JobOper_Row0.OprSeq}).Take(1).FirstOrDefault().OprSeq)
                                          orderby JobOper_Row.OprSeq descending 
                                          select JobOper_Row.QtyCompleted).Take(1).Sum();

InfoMessage.Publish("5"); // ...and this one

// This correctly sets thisOpQtyComplete to the Qty Complete for this op (excluding the current transaction)
thisOpQtyComplete = (from JobOper_Row in Db.JobOper where JobOper_Row.JobNum == ttLDtl.JobNum
                                          && JobOper_Row.OprSeq == ttLDtl.OprSeq
                                          orderby JobOper_Row.OprSeq descending
                                          select JobOper_Row.QtyCompleted).Take(1).FirstOrDefault();

InfoMessage.Publish("6"); // You know what I am going to say                                      

// Add the value of thisOpQtyComplete with ttLDtl.LaborQty to get the total completed for this op (including current transaction)
totalQtyComplete = thisOpQtyComplete + ttLDtl.LaborQty;

InfoMessage.Publish("7"); //Why am I bothering to enter these comments still?

InfoMessage.Publish(string.Format("Previous Operation Completed: {1}{0}This Op Completion: {2}{0}Total Completion: {3}", Environment.NewLine, prevOpQtyComplete, ttLDtl.LaborQty, totalQtyComplete)); 

InfoMessage.Publish("8"); // Seriously, nobody is going to read this but me!

// THIS SEEMS TO BE CAUSING AN ISSUE OF SOME SORT ISSUE
// Basically, if totalQtyComplete is more than what the previous operation 
// has made available (prevOpQtyComplete), then set tooMany to true, else false. 
// This is used in a conditional check in the next step of the BPM
if (totalQtyComplete > prevOpQtyComplete) { tooMany = true; } else { tooMany = false; }

InfoMessage.Publish("9"); // F-it...I'm this far...I may as well do this one too

InfoMessage.Publish(string.Format("You are able to close this job because there have been {0} completed parts in the previous operation, and you are completing less than that, with a total of {1}", prevOpQtyComplete.ToString(), ttLDtl.LaborQty));

Now if I put a value of 10 into LaborDtl.LaborQty when closing out the op, I will see all 9 message boxes appear, and the BPM continues on as it should. This is because the value of totalQtyComplete would not be greater than what is provided from the previous operation.

However, if I put in a value that would cause totalQtyComplete to be greater than the previous operation complete, none of those 9 message boxes appear, and the BPM powers through the rest of the steps.

Is there something with how BPM’s work that would stop the InfoMessage’s from appearing?

Maybe I’m reading it wrong, but aren’t you saying the same thing in both paragraphs?

Is the code block the only thing you’ve got in the BPM? Is there a condition block ahead of it?

So are you saying not even the message at the beginning appears but the actual operations/code is executed?

Are you completely 100% sure the code is actually executing and it is just the messages not appearing?

Maybe try some sort of database insert into a ud table to be able to confirm this.

Either this code block is not actually running, or you found a bug in the publish message logic, which to be fair I have no idea how they do it, considering the bpm is server side and the messages appear in the UI in a synchronized flow, it could be somewhat complex.

@jhecker I have noticed (I believe) that messages get somehow held and then all fire or don’t together. I use WriteEntry for debugging for this reason and I can leave them in place for troubleshooting.

I almost always have a start and end of bpm to know if it fired at all.

FWIW… on some Labor Entry where I’ve needed multiple messageboxes

  • I ended up putting the code right in the the form customization
  • I’m (pretty) sure it could be done in the BPM with widgets but… looked like a lot more work.

You are correct, I did not proof read my post very well. I have fixed it now.
Regarding what is all happening in the BPM, here is that information:

  1. If LaborDtl.RowMod = “U”, then continue on.
    a. If it is “A”, that means it is being called during “Start new production activity”, which is not what we want.
  2. This is an old conditional that was in place which always returns true. I had it for debugging purposes and failed to remove it before this screenshot was taken.
  3. This is the custom code block that was posted earlier
  4. This checks to see if ‘tooMany’ in the code above was set to true. If so, it moves onto #5, if not, it goes to #6.
  5. Raise Exception saying “Hey, you can’t complete more than what was completed in the previous op”
  6. Just a Message box saying “good to go” (just for debugging…it will be removed when I put it into production)

When I supply a value that is more than allowed, the Raise Exception box does get triggered and is displayed, however the InfoMessage.Publish messages from the code block never appear. So I know the BPM is firing all the way through, it just seems to ‘overlook’ some steps.

When I put in a valid value, I get all of the InfoMessage messages, and the “good to go” message.

Ahh, ok.

The messages are Queued. If you do a raise exception they will not show at all. The Exception shows instead of the info messages. If you have access to the server event logs, I’d use Ice.Diagnostics.Log.WriteEntry instead … then you can see the progess in the event viewer.

just commenting that the logic in your queries in the C# code do not take into account Jobs that have multiple Sub-Assemblies… This could cause problems if someone attempts to use this same logic and they have that scenario.

@timshuwy - you are correct with your observations on the logic. And thank you for bringing that up so that who may see the block of code will realize it is not something that can be dropped into any environment.
Now, I did think of that while I was throwing it together, but 2 things prompted me not to go that route:

  1. Nothing that we do here has any sub-assemblies/components.
  2. Modifying the code would require the need to press CTRL-SHIFT in the editor to highlight blocks of text with the arrow keys, and I am trying to get myself out of that habit, because as we all know, doing that in the E10.2 editor is not something that I would wish upon anyone. :rofl:

Up until this thread yesterday, I was unaware that Epicor queued info messages like that. That explains SOOO many of the headaches I have had through the years when using simple info messages for debugging.

I am going to look into using Ice.Diagnostics.Log.WriteEntry as suggested and see how that goes. Thank you for pointing that out :slight_smile:

EDIT: That is SOO much more convenient than InfoMessage.Publish()! Thank you for pointing out that lovely gem! (…as I begin to re-think my entire existence of debugging Epicor)