Designing a BPM to fill a text box from a field in a different table

Hey All.

I’m attempting to populate a text box on invoice entry from a related field on customer maintenance.

I’m new to C# and Epicor, would anyone be willing to take a look at my code in the BPM custom code window and give me some advice as to where I’m going wrong?

Error message received is
“Error CS0103: The name ‘Customer_iterator’ does not exist in the current context”

Again, very novice at this and would appreciate any help solving this problem. This BPM is running on the ARInvoice object on getNewInvcHead and the custom field name is Rebate_Grp_c.

Thanks,
Andrew

You need to give Customer_iterator a type in your foreach loop. Where the cursor is in your screenshot, add ‘var’ so that it reads ‘foreach (var Customer_iterator in (… the rest of the statement’

1 Like

Thank you for responding. I did try this but received the same error message.

Ah! I see now. Your first foreach is only a statement, rather than the beginning of a block. Your second foreach block should be nested inside of the first one. See below:

foreach (var Customer_iterator in (from Customer_Row in Db.Customer where Customer_Row.Company == ttInvcHead_xRow.Company && Customer_Row.CustNum == ttInvcHead_xRow.CustNum select Customer_Row))
{
  foreach (var CustItem in Customer_iterator)
  {
     ttInvcHead.RebateGrp_c = Customer_iterator.RebateGrp_c;
  }
}

EDIT: Looking at it again, you don’t need the second foreach block:

foreach (var Customer_iterator in (from Customer_Row in Db.Customer where Customer_Row.Company == ttInvcHead_xRow.Company && Customer_Row.CustNum == ttInvcHead_xRow.CustNum select Customer_Row))
{
  ttInvcHead_xRow.RebateGrp_c = Customer_iterator.RebateGrp_c;
}
2 Likes

It liked the syntax of that much better, but is now indicating that I’m missing an assembly reference. Any suggestions on where to proceed from here? Sorry to be a bother, again thank you so much for your time. (Error message posted below)

Error CS1061: ‘Erp.Tablesets.InvcHeadRow’ does not contain a definition for ‘RebateGrp_c’ and no extension method ‘RebateGrp_c’ accepting a first argument of type ‘Erp.Tablesets.InvcHeadRow’ could be found (are you missing a using directive or an assembly reference?) [GetNewInvcHead.Pre.rebategrp2.cs(121,19)]

No problem at all.

Since this is a custom UD field, you can’t use the dot notation to access it (I should have caught this earlier). You need to use bracket accessors:

ttInvcHead_xRow["RebateGrp_c"] = Customer_iterator["RebateGrp_c"];

I’m assuming that the field holds string/varchar information, but generally when you use this method to pull information out of a UD field, you need to cast it to the correct type after accessing it:

string output = Customer_iterator["RebateGrp_c"].ToString();

However, in this case I think it’s ok to not use the ToString, since you’re just storing it directly into another UD field.

Let me know if this gets you going.

2 Likes

Ended up trying this and another version where I did not include .ToString. Ended up returning to this error message:

Server Side Exception
There is at least one compilation error.
Exception caught in: Epicor.ServiceModel

Error Detail

Description: There is at least one compilation error.
Details:
Error CS0103: The name ‘Customer_iterator’ does not exist in the current context [GetNewInvcHead.Pre.rebategrp2.cs(122,36)]

foreach(var InvHead in ttInvcHead.Where(h => h.Added() || h.Updated()))
{
 var myCust =  Db.Customer.Where(c => c.Company == InvHead.Company && c.CustNum ==  InvHead.CustNum).FirstOrDefault();
 if(myCust != null)
 {
  InvHead["RebateGrp_c"] = myCust["RebateGrp_c"];
 }
}
2 Likes

Hey Chris, thank you for your help!

This compiled great, but I still can’t get the textbox to populate when a new invoice is created. Do you have a suggestion as to what method direction this should go under?

sometimes it is difficult to figure out the right method for these types of processes… in those cases, I tend to add the code to a DATA BPM, and only run it for ADDED rows.

3 Likes

Thank you, I changed to data directive and it works great!

1 Like

I see Tim has you working. Glad to see it. The issue is that for a GetNew, the system generated row you created is called AFTER your pre-process. Another way to solve this would be to just remove the .Where(Updated\Added) part and put it in a POST process. We can get away with this only because the GetNew doesnt actually create a record in the DB (but it still chews up your RowMod)

2 Likes

I have run into multiple processes where it is just difficult to capture the data via a regular Method BPM… for example, if you want to capture and tweak the OrderRel record as it is created, you just can’t get to it (or at least I haven’t found a way). But you CAN get to it as it is being added with a Data directive.
also, some data arrives in the database using multiple methods… Sales orders can be manually entered, Pulled from a Quote, Pushed from a quote, moved in from ECC, and even “duplicated”… each of these may use a different business object… but they ALL go through data directives.

1 Like

Thank you for your insight on this, didn’t realize that dynamic

1 Like