How can i add an expression/calculation to a Part Maintenance field?

I am trying to add a field (Combined Price) into the part master that would be the sum of the Part.UnitPrice(Casting Price) + Part.InternalUnitPrice (machine Shop Price) but i cant figure out how to add an expression or how to edit the script editor to accomplish this.

image

whats my best option for this?

I would say, add a UD field for it and update it via BPM on Update. So if either one changed then recalc that field. Then just bring it in via the customization.

If you don’t want a UD field and just want it as a client-side visual, then you’ll need the Customization to recalc this field any time those fields change/new part is brought in. I think the bases you’d need to cover are EpiNotify and OnFieldChanged events for both of the other prices.

1 Like

Brendan,

So ive started creating the BPM. I made the condition that if either of the two fields change to carry out the next action. My problem is i know pretty much nothing about the C# language so im not quite sure how to go about having it update the field.

With my limited knowledge im expecting it to be something along the lines of:

{
Insert_update
Part.UserDecimal = Part.UnitPrice + Part.InternalUnitPrice
}

But im sure theres much more to it than that

No worries Joe, you actually shouldn’t need to write C# for something this simple. There’s a Set Field module (or block or whatever those icons are called) you can use to set the field of the updated row to an expression. You may also want to consider expanding the Condition statement to include added rows so any new rows with those prices will trigger a calculation. Then here your Set Field would use 'set ___ field of the CHANGED row…", Example Below:

BUT If you’d like to explore the C# aspect, one way to do it might look like this:

var Part_xRow = (from ThisPart in ttPart where
ThisPart.Company == Session.CompanyID &&
(ThisPart.RowMod == IceRow.ROWSTATE_ADDED ||
ThisPart.RowMod == IceRow.ROWSTATE_UPDATED
select ThisPart).FirstOrDefault();

if(Part_xRow != null)
{
Part_xRow.CalcField_c = Part_xRow.Price1 + Part_xRow.Price2;
}

Either im missing something or a new version has moved the module but im not seeing an option to drag over the Set Field module. The only one i have is set BPM field but that shows different options as shown in the pictures below. Im signed is as the admin so i cant imagine this being a security issue. for the record we are running 10.1.600.7

Does it matter which group i have my bpm in?


Ah ok your problem there is you’re using a Standard Data Directive. What you want to use is a Pre-Processing Method Directive. You should see Set Field in there on your version.

If you have an Insights booklet for any of the BPM courses they have a pretty good description of the different kinds of Directives and the different between Standard vs In-Transaction Data Directives and Pre-Base-Post-Processing Method Directive. In general though, use In-Transaction for Data Directives and use Pre/Post Method Directives. Standard DDs and Base MDs are special.

What you usually want to use, especially for little things like this, is a Method Directive. MDs use the business objects and essentially just extend functionality. A hypothetical example would be that if a change to the Part table UnitCost would cause the PartCost table to update values, that would happen via the business objects. a Method Directive would respect that and make sure that happened alongside your code (if valid).

A Data Directive is more like a database trigger, where the business objects are ignored. In the same example if we changed UnitCost, the PartCost table values wouldn’t update and could then fall out of alignment. Essentially just saying “Just do what I say, only what I say, and nothing else”. This is useful if Epicor is doing something you don’t want it to do. However in most scenarios, if you CAN use a Method Directive then you should. That’s my best attempt at describing those if you weren’t aware. Someone with more years on here might have a better explanation.

2 Likes

Also, if your question about BPM Groups referred to this field:

image

Then no it doesn’t matter. That field is just for tracking purposes so you can write a bunch of related BPMs (Method and Data Directives) and keep them organized. You can open BPMs by group and Import/Export BPMs by group. Super helpful if you’re doing bigger projects that require several BPMs to accomplish. I personally like the practice of giving every BPM a group name.

1 Like

This worked perfectly. I was able to have the two part fields update the 3rd combined field upon save. Thank you for your help.

Can i call on another table (OrderDtl) from within the part table i just created this BPM in? I want this combined field to talk and update the unit price field on the Sales Order as well. Im having trouble finding exactly where that connection would be made

If you wanted to do it in the form, so the total shows in real time (i.e. when the user changes either of the 2 inputs):

Use the form event wizard to make a BeforeFieldChange event for either of the two input fields. And set code as follows:
(my example uses the built-in Part.UserDecimalxx fields, with UD1 and UD2 as the inputs, and UD3 as the total)

private void Part_BeforeFieldChange(object sender, DataColumnChangeEventArgs args)
	{
		// ** Argument Properties and Uses **
		// args.Row["FieldName"]
		// args.Column, args.ProposedValue, args.Row
		// Add Event Handler Code
		
		decimal total=0;
		
		switch (args.Column.ColumnName){
			case "UserDecimal1":
				total = Convert.ToDecimal(args.ProposedValue) + Convert.ToDecimal(args.Row["UserDecimal2"]);
				args.Row["UserDecimal3"] = total;
				break;
			
			case "UserDecimal2":
				total = Convert.ToDecimal(args.ProposedValue) + Convert.ToDecimal(args.Row["UserDecimal1"]);
				args.Row["UserDecimal3"] = total;
				break;
		}
	}

Some Notes:

  1. The control for UserDecimal3 should be read only, otherwise users could change it to something other than the sum of the other two fields.
  2. The value in UserDecimal1 or UserDecimal2 has to actually change to update UserDecimal3.

Are you using Part.UnitPrice? Order Lines should pull in the UnitPrice automatically. So if you’re not using it then just have the BPM write to the UnitPrice as well/instead of your Combined field. Then it should just work.

If you’re already using UnitPrice as something else and instead want CombinedPrice to pull in when making a new Order line, that might be a BPM set on the SalesOrder or a Data DIrective on Order Dtl. However, in that case I would just save myself the effort and move my fields around so that UnitPrice ends up being the calculated field so I didn’t have to do anything. A couple of DMTs would have you there. All depends on what you wanna do.

1 Like

Yea i think using UnitPrice as the combined field is easier overall than trying to change up the way the system sees it. Thanks for the info.