How to Delete Release using a Custom Action

Hi All!
This is a complicated issue with a lot of moving parts, for the sake of simplicity I have broken it down to just one question for now. First some background:

We are populating table UD02 with a list of open releases as requested by a client. This list changes every week and we are expected to keep our orders/releases up to date based on their changes.

So I loaded the UD02 table with all the orders I need to review.

Next I use a set of updatable BAQs to compare existing order releases in Epicor with the expected order releases in UD02. If any of our orders in Epicor do not match, then we want to close the release and delete it. I can close the release just fine with the code below. But I can’t figure out how to delete the release. In this example I am trying to delete the first release on a line.

I can’t find the BO or method for deleting a release. In the code below MyOrder = the order number, MyLine = the line number, and MyVar = SalesOrder Tableset.

using (Erp.Contracts.SalesOrderSvcContract soSvc =  Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.SalesOrderSvcContract>(Db))
       {
         soSvc.CloseRelease(MyOrder, MyLine, 1);
         soSvc.Update(ref MyVar);  
       }
}

Side question: Can DeleteByID() be used to delete a release, not an order?

I have run a trace when deleting a release, but I don’t recognize any of the methods as a delete method. Perhaps I need to set RowMod=“D”, but I can’t get the syntax to work for that in a custom action.

I understand that you can’t delete a release if it is the only one left on a line, and you can’t delete a release if something has shipped on it. Neither of these cases apply to my specific issue. I can expand on this further if it is helpful, but I don’t want to get you all side-tracked.

Thank you for your time,
Nate

You should be able to use the SO BO to GetByID to load your order into a dataset.

In the dataset, you can go down to the Release table, set the rowmod = “D” on the desired releases, then at end, Call an Update on the BO passing the working ds.

Hi Chris!
Thanks for the reply. I have done the first step, but how do I “go down to the Release table, set the rowmod = “D” on the desired releases”?

Thanks!
Nate

Assuming you already did your GetByID and have the resulting record in a SalesOrderTableset (SOTS below).

Something like this should work. You’ll probably need to include using Erp.Tablesets;

SalesOrderTableset SOTS = SOBO.GetByID(order);  
var desiredReleases = SOTS.OrderRel.Where(r => r.OrderLine == WantedLIne && r.OrderRelNum == WantedReleaseNum); //adjust where clause to meet your criteria
foreach(var rel in desiredReleases)
{
   rel.RowMod = "D";
}

SOBO.Update(SOTS);

I typed Erp.Tablesets; into the custom usings box, as I couldn’t find anassembly reference to add. I created MyVar4 using the GetByID BO.

Here is my attempt with errors:

What does this little bit do?

I forgot to put “using” in front of the tableset. but now I still get errors:

‘SalesOrderTableset’ does not contain a definition for ‘GetByID’ and no accessible extension method ‘GetByID’ accepting a first argument of type ‘SalesOrderTableset’ could be found (are you missing a using directive or an assembly reference?)

‘SalesOrderTableset’ does not contain a definition for ‘Update’ and the best extension method overload ‘IceDataContextExtensions.Update(ObjectSet, SalesOrderTableset)’ requires a receiver of type ‘ObjectSet’

Have a look at my example again. Notice there are 2 objects:
SOTS = SalesOrderTableset (the results)
SOBO = SalesOrder BO (this would be soSvc in your initial code)

The .Where allows you to put criteria on the releases you want to select. Once selected, you iterate over all selected releases and set the rowmod.

Thanks Chris! This worked great. Here is what I ended up with:

using (Erp.Contracts.SalesOrderSvcContract soSvc =  Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.SalesOrderSvcContract>(Db))

if (IsNewLine == true)
{

SalesOrderTableset SOTS = soSvc.GetByID(MyOrder);  
var desiredReleases = SOTS.OrderRel.Where(r => r.OrderLine == MyLine && r.OrderRelNum == 1); //adjust where clause to meet your criteria
foreach(var rel in desiredReleases)
{
   rel.RowMod = "D";
}

soSvc.Update(ref SOTS);

}

However, I am still unclear on the little “r=>” in the where clause. I understand what the where clause is. I am just not getting that first little r equals or greater than part.

the r is a reference to the table you are searching. So in your case it is a reference to the OrderRel table.

Right, I understand that r.OrderLine references the OrderLine from the OrderRel table. but I don’t understand what the first part of the where criteria is filtering for. What does r = > do? Normally I wouldn’t have that in there for a where clause. I would have written it as:

var desiredReleases = SOTS.OrderRel.Where(r.OrderLine == MyLine && r.OrderRelNum == 1);

Sure but you need to declare the reference. That is what the first part is.

The way you have it written the compiler doesn’t know what r is.

OK. Thanks Ken. I figured it was just a weird syntax thing.

Here is a quick overview of Lambda expressions.

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions

There are probably better ones out there.

1 Like

The code did work on my last test case. But Now that I am trying another case, I get an error that I can’t trace for the life of me!

In this test case I am adding two releases to a new line on a closed order. First I reopen the order with the BO, then I use the same process I had before to add the new lines and update the releases. I tried to run a trace to see if I could glean any extra information. How do I tell what line of code this error is referencing? I went through each of my custom code elements and added junk code to see if I could get the line number to change, maybe to help point me towards the right section, but no matter what I added or removed the line is always 73 and column is 17.

When I run now I get this error:

Business Layer Exception

The table queryResultDataset.Results has more than one record

Exception caught in: Epicor.ServiceModel

Error Detail

Description: The table queryResultDataset.Results has more than one record
Program: Epicor.Customization.BPM.dll
Method: GetSingleRow
Line Number: 73
Column Number: 17
Table: queryResultDataset.Results

Client Stack Trace

at Epicor.ServiceModel.Channels.ImplBase1.ShouldRethrowNonRetryableException(Exception ex, DataSet[] dataSets) at Ice.Proxy.BO.DynamicQueryImpl.RunCustomAction(DynamicQueryDataSet queryDS, String actionID, DataSet queryResultDataset) at Ice.Adapters.DynamicQueryAdapter.<>c__DisplayClass33_0.<RunCustomAction>b__0(DataSet datasetToSend) at Ice.Adapters.DynamicQueryAdapter.ProcessUbaqMethod(String methodName, DataSet updatedDS, Func2 methodExecutor, Boolean refreshQueryResultsDataset)
at Ice.Adapters.DynamicQueryAdapter.RunCustomAction(DynamicQueryDataSet queryDS, String actionId, DataSet updatedDS, Boolean refreshQueryResultsDataset)
at Ice.UI.App.BAQDesignerEntry.BAQTransaction.<>c__DisplayClass384_0.b__0(Int32& rowReturned)
at Ice.UI.App.BAQDesignerEntry.Forms.BAQDiagramForm.ShowQueryResults(DataSet dsResults, getQueryResult getResults, ReportAdditionalInfo additionalInfo)
at Ice.UI.App.BAQDesignerEntry.BAQTransaction.CallRunCustom()

Here are the three custom code elements I have in place now, and an image of my process.
PullInData

var ttResults_xRow = (from ttResults_Row in ttResults where ttResults_Row.Calculated_NewRelease == true select ttResults_Row).First();
if (ttResults_xRow != null)
{
  IsNewLine=false;
  totalrows = ttResults.Count / 2; //not sure why this is divided by 2, but it works...
  if (myrow <= totalrows)
    {
        MyOrder = ttResults_xRow.OrderHed2_OrderNum;
        if (String.IsNullOrEmpty(Convert.ToString(ttResults_xRow.OrderDtl1_OrderLine)))
        {
          MyLine = 0;
        }
        else
        {
          MyLine = ttResults_xRow.OrderDtl1_OrderLine;
        }
        MyQty = ttResults_xRow.UD02_Number01;
        MyDate = ttResults_xRow.UD02_Date01;
        MyPart = ttResults_xRow.UD02_ShortChar01;
        ttResults_xRow.Calculated_NewRelease = false;
    }
}

SetMyLine

var OrderDtl = (from row in Db.OrderDtl where row.Company == Session.CompanyID && row.OrderNum == MyOrder orderby row.OrderLine descending select row).FirstOrDefault();
     {
      MyLine = OrderDtl.OrderLine;
     }
IsNewLine=true;

DeleteFirstRel

using (Erp.Contracts.SalesOrderSvcContract soSvc =  Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.SalesOrderSvcContract>(Db))
{
  if (IsNewLine = true)
  {
    SalesOrderTableset SOTS = soSvc.GetByID(MyOrder);  
    var desiredReleases = SOTS.OrderRel.Where(r => r.OrderLine == MyLine && r.OrderRelNum == 1);
    foreach(var rel in desiredReleases)
    {
       rel.RowMod = "D";
    }
    soSvc.Update(ref SOTS);
  }
}

Should I migrate this to a new topic? I think the question of how to delete a release in a custom action is answered.

1 Like