Simple BPM Question

,

So I would like to copy the comments automatically when a Quote is converted to an Order using a BPM Method Directive.

It does not seem like this BPM is being triggered.

Can someone give me some advice here?

There are two ways to convert which each trigger it’s own method directive.

  • From SO Entry, Actions -> Get Opportunity/Quote. This one triggers SalesOrderEntry.CreateOrderFromQuote

  • From Opp/Quote Entry, Actions -> Quote -> Create Sales Order. This one triggers Quote.CreateOrder

Which screen are you converting from?

I’ve tried both places and neither seems to be triggering, but I am using the Get Opportunity/Quote under the sales order screen. I figured once I had it working correctly, I would update & migrate to the other location. I have tried this equivalent setup in the pre and post locations and neither seems to trigger.

I would put a simple popup in the directive to be sure it’s firing.

Got it now, need to do from the Quote side but a huge thanks to @timshuwy for the assist to set me on the correct path! Solution is like this:

based on: Help debugging BPM Code

First Query setter adds to the dataset for the comments desired.
Second and Third fill the UpdExtSalesOrderTableset appropriate lines/header fields respectively.
Last use the BO to update the recordset in the DB. Hurray!

1 Like

Well as this is only 1/2 of the solution I tried implementing a similar solution on the Quote Create Order and getting an error.

Here is the code:

using (var txtScope=IceContext.CreateDefaultTransactionScope())
  {
  using (var svc=Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.SalesOrderSvcContract>(Db)) 
    {
    var tsUESO = new Erp.Tablesets.UpdExtSalesOrderTableset();
    var ttSOHed_xRow = (from ttOrderHead_Row in Db.OrderHed where ttOrderHead_Row.Company == Session.CompanyID && ttOrderHead_Row.OrderNum == orderNum select ttOrderHead_Row).FirstOrDefault();
    
    //Need to first set header fields in tsUESO
    var ohRow = new Erp.Tablesets.OrderHedRow();
    ohRow.Company = ttSOHed_xRow.Company;
    ohRow.OrderNum = ttSOHed_xRow.OrderNum;
    tsUESO.OrderHed.Add(ohRow);
    
    //Next iterate rows and add them in tsUESO
    var ttSODtl_Rows = (from ttOrderDtl_Rows in Db.OrderDtl where ttOrderDtl_Rows.Company == Session.CompanyID && ttOrderDtl_Rows.OrderNum == orderNum select ttOrderDtl_Rows);
    //Fill OrderDtl Rows next and add to tsUpdExt
    foreach (var SODRow in ttSODtl_Rows)
      {
      var odRow = new Erp.Tablesets.OrderDtlRow();
      odRow.Company = SODRow.Company;
      odRow.OrderNum = SODRow.OrderNum;
      odRow.OrderLine = SODRow.OrderLine;
      odRow.ShipComment = SODRow.PickListComment;
      odRow.InvoiceComment = SODRow.OrderComment;
      odRow.ProFormaInvComment = SODRow.OrderComment;
      tsUESO.OrderDtl.Add(odRow);
      }
    bool errorsOccurred;
    BOUpdErrorTableset ErrorTableset = svc.UpdateExt(ref tsUESO, false,true, out errorsOccurred);
    //Update and exit
    Db.Validate();
    txtScope.Complete();
    }
  }

Here are the error(s):

Server Side Exception

There is at least one compilation error.
CreateOrder.CommonTypes.cs(316,33): error CS0433: The type 'QuoteQtyTable' exists in both 'Erp.Contracts.BO.Quote, Version=10.2.400.0, Culture=neutral, PublicKeyToken=5d3fa3c7105d7992' and 'Erp.Contracts.BO.SalesOrder, Version=10.2.400.0, Culture=neutral, PublicKeyToken=5d3fa3c7105d7992'
CreateOrder.CommonTypes.cs(341,33): error CS0433: The type 'HedTaxSumTable' exists in both 'Erp.Contracts.BO.Quote, Version=10.2.400.0, Culture=neutral, PublicKeyToken=5d3fa3c7105d7992' and 'Erp.Contracts.BO.SalesOrder, Version=10.2.400.0, Culture=neutral, PublicKeyToken=5d3fa3c7105d7992'
CreateOrder.CommonTypes.cs(346,33): error CS0433: The type 'PartSubsTable' exists in both 'Erp.Contracts.BO.Quote, Version=10.2.400.0, Culture=neutral, PublicKeyToken=5d3fa3c7105d7992' and 'Erp.Contracts.BO.SalesOrder, Version=10.2.400.0, Culture=neutral, PublicKeyToken=5d3fa3c7105d7992'
CreateOrder.CommonTypes.cs(351,33): error CS0433: The type 'TaxConnectStatusTable' exists in both 'Erp.Contracts.BO.Quote, Version=10.2.400.0, Culture=neutral, PublicKeyToken=5d3fa3c7105d7992' and 'Erp.Contracts.BO.SalesOrder, Version=10.2.400.0, Culture=neutral, PublicKeyToken=5d3fa3c7105d7992'
CustomizationAdapter.cs(329,30): error CS0433: The type 'ETCAddrValidationTableset' exists in both 'Erp.Contracts.BO.Quote, Version=10.2.400.0, Culture=neutral, PublicKeyToken=5d3fa3c7105d7992' and 'Erp.Contracts.BO.SalesOrder, Version=10.2.400.0, Culture=neutral, PublicKeyToken=5d3fa3c7105d7992'
CustomizationAdapter.cs(9,132): error CS0738: 'QuoteSvcCustomization' does not implement interface member 'QuoteSvcContract.ETCValidateAddress(int, int, out bool, out bool, out string)'. 'QuoteSvcCustomization.ETCValidateAddress(int, int, out bool, out bool, out string)' cannot implement 'QuoteSvcContract.ETCValidateAddress(int, int, out bool, out bool, out string)' because it does not have the matching return type of 'ETCAddrValidationTableset'.
CreateOrder.CommonTypes.cs(152,55): error CS0433: The type 'QuoteQtyRow' exists in both 'Erp.Contracts.BO.Quote, Version=10.2.400.0, Culture=neutral, PublicKeyToken=5d3fa3c7105d7992' and 'Erp.Contracts.BO.SalesOrder, Version=10.2.400.0, Culture=neutral, PublicKeyToken=5d3fa3c7105d7992'

Exception caught in: Epicor.ServiceModel

Error Detail 
============
Description:  There is at least one compilation error.
Details:  
CreateOrder.CommonTypes.cs(316,33): error CS0433: The type 'QuoteQtyTable' exists in both 'Erp.Contracts.BO.Quote, Version=10.2.400.0, Culture=neutral, PublicKeyToken=5d3fa3c7105d7992' and 'Erp.Contracts.BO.SalesOrder, Version=10.2.400.0, Culture=neutral, PublicKeyToken=5d3fa3c7105d7992'
CreateOrder.CommonTypes.cs(341,33): error CS0433: The type 'HedTaxSumTable' exists in both 'Erp.Contracts.BO.Quote, Version=10.2.400.0, Culture=neutral, PublicKeyToken=5d3fa3c7105d7992' and 'Erp.Contracts.BO.SalesOrder, Version=10.2.400.0, Culture=neutral, PublicKeyToken=5d3fa3c7105d7992'
CreateOrder.CommonTypes.cs(346,33): error CS0433: The type 'PartSubsTable' exists in both 'Erp.Contracts.BO.Quote, Version=10.2.400.0, Culture=neutral, PublicKeyToken=5d3fa3c7105d7992' and 'Erp.Contracts.BO.SalesOrder, Version=10.2.400.0, Culture=neutral, PublicKeyToken=5d3fa3c7105d7992'
CreateOrder.CommonTypes.cs(351,33): error CS0433: The type 'TaxConnectStatusTable' exists in both 'Erp.Contracts.BO.Quote, Version=10.2.400.0, Culture=neutral, PublicKeyToken=5d3fa3c7105d7992' and 'Erp.Contracts.BO.SalesOrder, Version=10.2.400.0, Culture=neutral, PublicKeyToken=5d3fa3c7105d7992'
CustomizationAdapter.cs(329,30): error CS0433: The type 'ETCAddrValidationTableset' exists in both 'Erp.Contracts.BO.Quote, Version=10.2.400.0, Culture=neutral, PublicKeyToken=5d3fa3c7105d7992' and 'Erp.Contracts.BO.SalesOrder, Version=10.2.400.0, Culture=neutral, PublicKeyToken=5d3fa3c7105d7992'
CustomizationAdapter.cs(9,132): error CS0738: 'QuoteSvcCustomization' does not implement interface member 'QuoteSvcContract.ETCValidateAddress(int, int, out bool, out bool, out string)'. 'QuoteSvcCustomization.ETCValidateAddress(int, int, out bool, out bool, out string)' cannot implement 'QuoteSvcContract.ETCValidateAddress(int, int, out bool, out bool, out string)' because it does not have the matching return type of 'ETCAddrValidationTableset'.
CreateOrder.CommonTypes.cs(152,55): error CS0433: The type 'QuoteQtyRow' exists in both 'Erp.Contracts.BO.Quote, Version=10.2.400.0, Culture=neutral, PublicKeyToken=5d3fa3c7105d7992' and 'Erp.Contracts.BO.SalesOrder, Version=10.2.400.0, Culture=neutral, PublicKeyToken=5d3fa3c7105d7992'
Program:  Epicor.Customization.Core.dll
Method:  Compile
Line Number:  78
Column Number:  13

Client Stack Trace 
==================
   at Epicor.ServiceModel.Channels.ImplBase`1.ShouldRethrowNonRetryableException(Exception ex, DataSet[] dataSets)
   at Ice.Proxy.BO.BpMethodImpl.Update(BpMethodDataSet ds)
   at Ice.Adapters.BpMethodAdapter.OnUpdate()
   at Ice.Lib.Framework.EpiBaseAdapter.Update()
   at Ice.UI.App.BpMethodEntry.Transactions.MainTransactionBase.adapterUpdate()

If you are updating only comments field, try directly updating OrderDtl table using the BPM.

Soon as I add the Erp.Contracts.BO.SalesOrder reference it gives me the above error. Seems like I will need to put this in a DD vs MD and update on field change unless someone has a better idea?

I have had similar issues… This happens when you are trying to create a second instance of the contract. That means that the contract is already there.
As someone else suggested, you may need to move this to a DATA directive.
ALSO… I think the Data Directive will resolve a problem where your logic will only work when PULLING the quote into an order… but if you are in the QUOTE, and you PUSH the quote, it will take another BPM. Moving it to a data directive will always trigger.
Another (untested) approach in the latest versions of epicor would be to create an Epicor FUNCTION. Then call the function with parameters. You could then call the Epicor Function from both the Quote Push and the Order Pull BPms.

Ya. I did it this way using DD and widgets, but more brute force method I only added a check for already present field since it’s looking at changed rows.

Thanks everyone for looking!

Hi @timshuwy ,

I did test this approach and got the same error message.

In my case, I’m trying to default some UD fields in QuoteDtl that get pulled in from associated UD fields in Part. I created a Epicor Function that had two string parameters: InPart and OutPartTableSet. The EFx does a Part.GetList (which includes UD fields and is quick) , serializes the PartListTableSet into a Json string, and passes it back to the BPM. I created a variable of type PartListTableSet and deserialize the result into the variable. Apparently, declaring this variable is all that is needed to pull the entire contract in for the Part BO as I get the same error message. :frowning:

I reported this to Support (CS0002316420) but they wanted to refer me to PS. So today I see two possible solutions (besides the current kludgy proxy method noted in EpicCare) :

  • Convert the PartTableSet to a System.DataTable and add it to a DataSet to pass back to the BPM
  • Avoid the Part BO altogether and call a BAQ.

Other more talented and clever people than I may have some addition thoughts too.

As people move to 10.2.700+ and move this kind of code from Customizations to Functions/BPMs, we’re going to see this issue come up more often. Three times in November for just this community. I’m not sure where this is on the roadmap @Edge, as I know you’re aware of it, but it’s going to be happening more and more to users and the Professional Services team as people migrate to current releases.

Thanks!!!

Mark W.

Mark the team is addressing the issue with contract conflicts so that should help in the future.

2 Likes

Great to hear! Thanks so much @edge!

ughh hope it comes sooon. :sob:

So I am getting the same “error CS0433” when I try adding a SalesOrderTableset to a Quote BPM, or having a QuoteTableSet in a SalesOrder BPM.

This actually worked for me (in 2021.2.13). I can have both tablesets in a function and it isn’t erroring out for me. Thanks all for the info in this thread.

1 Like

Nice!