Update multiple tables with advanced BPM update

I am trying to update both the part and custxprt tables on a BAQ. I tried using the auto generated code to update both of these records using Advanced BPM Update, without any luck. Can someone provide me with a sample code they used to update multiple tables?

any ideas?

I don’t have access right now to any code to paste in here, but a good start is to create an updateable BAQ for each separately, then paste the code for both into the combined one. Obviously it won’t work just like that, but if you know Epicor code enough to follow someone else’s example then it’s almost as good. The auto generated code is a very solid base and not too hard to figure out.

Here’s a butchered bit of an Advanced BPM Update in case it helps (I’ve taken out a load of stuff that isn’t relevant except to our particular requirements). As you can see, except for having two SvcContracts in one it isn’t very different from the AutoGenerated code. You just need to sift the ttResults data for the bits you need for each update, assemble each UpdateExt tableset, and do both updates.

try
{
		Erp.Contracts.PriceLstSvcContract hPriceLst = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.PriceLstSvcContract>(Db);
		Erp.Contracts.CustomerSvcContract hCustomer = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.CustomerSvcContract>(Db);

		if (hPriceLst != null)
		{
				var specials = (from row in ttResults where  ...);
				if (specials.Count() > 0)
				{
						Erp.Tablesets.UpdExtPriceLstTableset ds = new Erp.Tablesets.UpdExtPriceLstTableset();
						bool errorOccurred;
						var pl = new Erp.Tablesets.PriceLstRow()
						{
								Company = Session.CompanyID,
								ListCode = spListCode,
								ListDescription = listDesc,
								StartDate = startdate,
								EndDate = enddate,
								...
								RowMod = "U"
						};
						... UD fields
						ds.PriceLst.Add(pl);

						foreach (var special in specials)
						{
								var plp = new Erp.Tablesets.PriceLstPartsRow()
								{
										Company = Session.CompanyID,
										ListCode = spListCode,
										PartNum = special.PartNum,
										UOMCode = special.UOM
								};
								if (special.Price == null || special.Price == 0)
								{
										plp.RowMod = "D";
								}
								else
								{
										plp.BasePrice = special.Price;
										plp.RowMod = "U";
								}
								... UD fields
								ds.PriceLstParts.Add(plp);
						}
				
						BOUpdErrorTableset boUpdateErrors = hPriceLst.UpdateExt(ref ds, true, true, out errorOccurred);

						if (errorOccurred && boUpdateErrors != null && boUpdateErrors.BOUpdError != null)
						{
								this.PublishInfoMessage(boUpdateErrors.BOUpdError[0]["ErrorText"].ToString(),Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual,"","");
								this.PublishInfoMessage(...,Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual,"","");
						}
				}
		}
	
		if (hCustomer != null)
		{
				int nextSeqNum = 1;

				if ((from row in Db.CustomerPriceLst where row.Company == Session.CompanyID && row.CustNum == iCustNum && row.ShipToNum == string.Empty select row).FirstOrDefault() != null)
				{
						nextSeqNum = ((int?)(from row in Db.CustomerPriceLst where row.Company == Session.CompanyID && row.CustNum == iCustNum && row.ShipToNum == string.Empty select row.SeqNum).Max() ?? 0) + 1;
				}

				Erp.Tablesets.UpdExtCustomerTableset ds = new Erp.Tablesets.UpdExtCustomerTableset();
				bool errorOccurred;
				var cust = new Erp.Tablesets.CustomerRow()
				{
						Company = Session.CompanyID,
						CustNum = iCustNum,
						RowMod = "U"
				};
				ds.Customer.Add(cust);

				var newPL = (from row in ttResults ...);
				
				foreach (var pl in newPL)
				{
						string listCode = pl.Calculated_NewListCode;
						var plrow = new Erp.Tablesets.CustomerPriceLstRow()
						{
								Company = Session.CompanyID,
								CustNum = iCustNum,
								ShipToNum = string.Empty,
								ListCode = listCode,
								SeqNum = nextSeqNum,
								RowMod = "A"
						};
						ds.CustomerPriceLst.Add(plrow);
						nextSeqNum++;
				}
	
				BOUpdErrorTableset boUpdateErrors = hCustomer.UpdateExt(ref ds, true, true, out errorOccurred);

				if (errorOccurred && boUpdateErrors != null && boUpdateErrors.BOUpdError != null)
				{
						this.PublishInfoMessage(boUpdateErrors.BOUpdError[0]["ErrorText"].ToString() + System.Environment.NewLine + p + System.Environment.NewLine + msg,Ice.Common.BusinessObjectMessageType.Error, Ice.Bpm.InfoMessageDisplayMode.Individual,"","");
						//this.PublishInfoMessage(...,Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual,"","");
				}
		}

		hCustomer.Dispose();
		hCustomer = null;
		hPriceLst.Dispose();
		hPriceLst = null;
}
catch (Exception e)
{
		this.PublishInfoMessage(... + e.Message,Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual,"","");
}
2 Likes

Hi,

new to updatable BAQ…

could you please explain where these codes are entered?

R,

new to updatable BAQ…

In which case you might be jumping into the deep end here.

Updateable BAQs in their basic form are quite simple. You go to the Update Processing tab, select “BPM Update”, and search for the right Business Object, then as long as all the right keys are in your BAQ, the correct working code is generated for you. If you want to learn how it’s done, you can click on “BPM Directives Configuration” and look at the various bits of codes generated as “#BASE#”.

If you want to do anything more elaborate, which in this thread’s case means updating two BOs from one BAQ, you have to create the code yourself by selecting “Advanced BPM Update”. You then have to add a new Base Processing directive for whichever actions you want, and write that code yourself using the relevant Business Objects. You can get a head start by doing a standard BPM Update first, letting the system generate the code, then copying and pasting that into an Advanced BPM directive to modify … but if this is all completely new to you, then I’d suggest you proceed with caution.

2 Likes

Thanks for the reply,

what I am trying to achieve is create an updatable dashboard to approve PO, so that I can give to mobile users and they can approve POs in mobile (by the way is there any other option to approve PO from mobile?)

once I start with this, I tried to update the column ApproverResponse in POApvMsg table, then it said the ApproveredAmt in POHeader to be set.

I tried to bring the ApproveredAmt in POHeader also to the dashboard and tried to update it.

I set the processing method to BPM Update and selected BO POApvMsg, went to to BPM Directives Configuration as you mentioned and I could not see any codes anywhere

should I edit the directive and write my own custom codes to update the fields?

If you click on the “Design” button, you’ll see the code is in fact there, it’s just not showing in this window. If a single BO is all you need, then there shouldn’t be much more to do anyway. Either way, it’s not a good idea to edit the auto-generated directive itself because the system could overwrite it any time.

Working with PO approvals can be quite tricky. It’s an Epicor cliche, but if I were you I would be working through a trace generated from doing what you want the system way first and seeing if you can recreate those steps.

1 Like

Thanks a lot,
I have to update two tables
let me try now…

Hi Sadik, I know this is an old post but did you ever get your uneatable dashboard for PO approval to work? Would you be willing to share your solution? We would like to use mobile for approving PO’s as well.

Thx,

Hi Daryl,

could you share a bit more of your code, I am looking for how you manage the UD fields.
For example, I added a UD field called ShipByTime_c to the TFOrdDtl table and I am trying to assign the value second to the UD field but the following does work.
var TFOrdDtl = new Erp.Tablesets.TFOrdDtlRow()
{
Company = ttResult.OrderHed_Company,
RequestDate = ttResult.OrderRel_ReqDate,
TFLineNum = ttResult.Calculated_TFLineNumCalc,
TFOrdNum = ttResult.Calculated_TFOrdNumCalc,
ShipByTime_c = second
};

Thank you,

Daniel

Hi Daniel,

UD fields need to be managed a bit differently.

var TFOrdDtl = new Erp.Tablesets.TFOrdDtlRow
{
   Company = ttResult.OrderHed_Company,
   RequestDate = ttResult.OrderRel_ReqDate,
   TFLineNum = ttResult.Calculated_TFLineNumCalc,
   TFOrdNum = ttResult.Calculated_TFOrdNumCalc,
};
TFOrdDtl.SetUDField<System.Integer>("ShipByTime_c",second);

That’s assuming your value is an integer.

You can only set existing fields in the initial assignment.

I’ve just copied your code and adjusted from memory, so apologies for any inaccuracy.

That worked.

Thank you!