Cannot create a loop with BPM widgets

So, I can’t do this, eh? That’s how I read the error.

I’m sure many of you are laughing at the idea of this code. I just want the next available PO number that is above number X but below the number in company configuration, so that this site can have its own PO number set.

Anyhow, I guess the only way to melt down the system is in C#? Yay.

Since this is on PO.Update, why not perform a check and if it fails the check, throw an exception?
That will prevent the PO.Update method from completing and will force the user to enter a “valid” number.
The next time they try to save, it will evaluate the condition again.

You can create loops but usually you need to have more than 1 widget in between (unless they changed that recently)

@Aaron_Moreng I might be misunderstanding what you mean, but I’m trying to generate the next number, not validate it.

Well, OK, I’m validating it, too, but it’s not from user input.

But AFAIK, each site cannot have its own sequence of PO numbers natively. You can manually enter a number lower than the starting number in company config, or use a BPM to do the same.

For what it’s worth, I made no changes to my BPM and it worked exactly as I wanted it to. The error in the designer is not a binding law, I guess.

1 Like

That validation is kind of crap… It doesn’t catch things that it should and, like you’ve found, raises problems that aren’t problems.

@Banderson Yeah I’m sorry for taking some of your time. I know that wasn’t meant as a guilt trip, but I feel silly now. Which is kind of your point.

No worries, I was just agreeing with you, that I never truly trusted it.

Here’s my very first attempt at LINQ code from scratch (so be gentle…)

I believe the following code in a Set Field Widget should work.

(from x in Db.POHeader where (x.PONum >= 10000 && x.PONum <= 30000) select x.PONum).Max()+1

Obviously only call it if you pass the condition for testing if its the target Plant

EDIT:

It does no error checking to see if a prior PO existed in that range of 10,000 to 20,000. If none exists it will error out.

Also, our Next PO Num in Company Maint is 35,000

2 Likes

The max idea is a more useful approach than mine, which would require no deleted PO numbers. And undoubtedly faster.

Like I said, that was my first attempt at LINQ code, so it may not be 100%. But it did work (as long as there was already one PO between 10,000 and 30,000)

When there isn’t, I think it the first part (from ... .MAX() returns a null, and it errors when trying to evaluate null + 1

I thought I could get even more clever, and do the plant check in that LINQ code, but the plant is not stored with the POHeader :frowning:

may i ask why you want to add plant check, if each company has its own sequence range then,

var ttPOHeader_xRow = (from ttPOHeader_Row in ttPOHeader
			 where ttPOHeader_Row.Added()
select ttPOHeader_Row).FirstOrDefault();
if(ttPOHeader_xRow != null)
{
var NextPONum = (from x in Db.POHeader where x.Company == ttPOHeader_xRow.Company  select x.PONum).Max()+1
//now you can assign NextPONum to ttPOHeader.PONum
// OR if you have that value stored in Company table then
var NextPONum = (from x in Db.Company where x.Company == ttPOHeader_xRow.Company  select x.YourCompanyLastPONumUDField)+1
}

Edit:
you can call this value from the plant table - if you decide to have different PONum range per plant not company- using the same principle, i.e. comparing to the session PlantID to get your record in Db.Plant table.

var NextPONum = (from x in Db.Plant where x.Company == ttPOHeader_xRow.Company  && x.Plant == Session.PlantID select x.YourPlantLastPONumUDField)+1

1 Like

because the OP said:

I assumed that to be, that they wanted different PONum ranges for different plants/sites, within the same company

thanks @ckrusen, i have posted the needed code for both cases

FOUR YEARS LATER…

Now that I’m not nearly as scared of BPMs, I finally gave this code a whirl, and it works great! Calvin, this was brilliant.

It literally was this simple. No usings or any coder stuff. Wish I had tried this earlier…

OK, right, I did add a few conditions (in widgets) ahead of the code, but the point is that the Set Field widget is truly this simple.

And it works in milliseconds. Yes!

1 Like