Converting E9 BPM ABL to E10

Hi, I am new to BPM ABL. I am trying to convert an E9 BPM for the OrderDtl to E10 but I have no concept at all. This is the BPM conditions:

and this is the actions:

My question is, how do I convert that to be used in E10. I am told that I will need to create C# codes for it, but I have not understanding of what the BPM is saying or doing, and how to begin to translate that to actual code.

Any help would be appreciated.

Thanks, R.

If you don’t know what the BPM is doing you are probably not the person who should be doing this translation. (No ofense)

Are you familiar with Epicor BPMs at all?

There is a Programmers guide on EpicWeb which can help, however I’d recommend you do not do this if you don’t understand the BPM.

1 Like

You might consider offloading this task to someone else, there is a pretty steep learning curve before you could make the conversion from ABL to C# you would need to understand both a pretty moderate level, to pull it off without issues.

1 Like

None taken at all. hehehe…

I am a fast learner and if I could generally understand that is happening in the image examples I attached, it could be a starting point.

In converting E9 BPMs to E10, I generally deconstruct the E9 BPM to the requirement: what does this BPM accomplish and what is the workflow? Then I rebuild using the E10 UI based on the requirement.
It’s not a great idea to try to translate ABL/4GL to C# line by line. If you have a lot of complex stuff, you might need technical assistance on one or both sides, or you could sit down with someone who is familiar with the business logic and have them talk you through the expectation delta from base functionality.

What’s the actual ABL code in the Action?

The conditions are:


in the code section is shows ‘’ and ? as seen.

The action:

and the ABL code is:

This seems fairly simple.

It looks like it says, “If the PricePerCode on the OrderDtl row is “” or null, set it to ‘E’ and also set ShortChar06 to ‘E’.” However, I’m not sure what the use case is because according to help, this value comes from either the Part record or Defaults to “E”, so I don’t believe it can be null…

Indicates the pricing per quantity. It can be “E” = per each, “C” = per hundred, “M” = per thousand. Used to calculate the extended unit price for the line item. The logic is to divide the OrderDtl.OrderQty by the appropriate “per” value and then multiply by unit price. Use the Part.PricePerCode as a default. If the Part record does not exist then default as “E”.

With that said, I think you accomplish this using just the widgets and no custom code, by using a condition like you have and the Set Field widget.

However, if you run that ABL through Epicor’s Online Conversion - Progress 4GL to C# (https://scrs.epicor.com/ABLConversionweb/)

You get this suggestion

foreach (var ttOrderDtl_iterator in (from ttOrderDtl_Row in ttOrderDtl
                                     where String.IsNullOrEmpty(ttOrderDtl_Row.PricePerCode) || ttOrderDtl_Row.PricePerCode == null
                                     select ttOrderDtl_Row))
{
    var ttOrderDtlRow = ttOrderDtl_iterator;
    ttOrderDtlRow.PricePerCode = "E";
    ttOrderDtlRow["ShortChar06"] = "E";
}
1 Like

Please do NOT use the converter in any real production code.! As @nhutchins said its a suggestion that should be re-written EVERY TIME.
That converter is no better than Google

Seriously, don’t use that

1 Like

Thank you for that. :smiley:

For the converted code, it seems that it is LINQ. Is that correct?

I know @josecgomez said not to use the converter, but I tried following the documentation and I was unable to write in the Programming Interface Generated Code window. No errors. I just could not enter any text.

I tried the converter mentioned by @nhutchins and got this code for an ABL:

Erp.Tables.quotedtl quotedtl;
foreach (var ttOrderDtl_iterator in (from ttOrderDtl_Row in ttOrderDtl
                                     where ttOrderDtl_Row.QuoteNum > 0 && ttOrderDtl_Row.QuoteLine > 0
                                     select ttOrderDtl_Row))
{
    var ttOrderDtlRow = ttOrderDtl_iterator;
    quotedtl = (from quotedtl_Row in Db.quotedtl
                where quotedtl_Row.Company == ttOrderDtlRow.Company && quotedtl_Row.quotenum == ttOrderDtlRow.quotenum && quotedtl_Row.quoteline == ttOrderDtlRow.quoteline
                select quotedtl_Row).FirstOrDefault();
    if (quotedtl != null)
    {
        ttOrderDtlRow["ShortChar07"] = (string)quotedtl["shortchar07"];
    }
} 

What I don’t get is the reference for the database table. I am not able to find that Erp.Tables reference so I can access the QuoteDtl table. Right now I am getting errors and it has to do with the namespace reference not existing.

What references do I need to access the mentioned table?

Why don’t you just use the widgets? The condition is:

if the change row is empty or null

then

set field PricePerCode to “E” and ShortChar06 to 'E"

All of that can be done with the normal condition block and the set fields block, unless I am missing something here.

3 Likes

This one I understand and have resolved, however, the one above, I do not understand how to access the QuoteDtl table.

Here is it again:

Erp.Tables.quotedtl quotedtl;
foreach (var ttOrderDtl_iterator in (from ttOrderDtl_Row in ttOrderDtl
                                     where ttOrderDtl_Row.QuoteNum > 0 && ttOrderDtl_Row.QuoteLine > 0
                                     select ttOrderDtl_Row))
{
    var ttOrderDtlRow = ttOrderDtl_iterator;
    quotedtl = (from quotedtl_Row in Db.quotedtl
                where quotedtl_Row.Company == ttOrderDtlRow.Company && quotedtl_Row.quotenum == ttOrderDtlRow.quotenum && quotedtl_Row.quoteline == ttOrderDtlRow.quoteline
                select quotedtl_Row).FirstOrDefault();
    if (quotedtl != null)
    {
        ttOrderDtlRow["ShortChar07"] = (string)quotedtl["shortchar07"];
    }
} 

I am not able to find that Erp.Tables reference so I can’t access the QuoteDtl table. Right now I am getting errors and it has to do with the namespace reference not existing.

What references do I need to access the mentioned table?

I figured out the reference I needed and now all but 1 of my error is occurring.

THE ERROR:
CS1061 ‘ErpContext’ does not contain a definition for ‘quotedtl’ and no extension method ‘quotedtl’ accepting a first argument of type ‘ErpContext’ could be found

It has something to do with the “Db” on this line:

from quotedtl_Row in Db.quotedtl

Does anyone know what the Db suppose to represent and how would I declare it?

If you are in BPM, you can use Ctrl+Space to give you an autocomplete similar to visual studios intellisense. So type "Db. " then hit Ctrl+Space, and it should give you a list of what’s available. It’s probably just a case issue (C# is case sensitive)

QuoteDtl

3 Likes

Beautiful. That helps a lot.

Thank you.

Does anyone know how to convert this particular BPM ABL code to C#? I am trying to see what the converter would do, but it keeps timing out.

Run lib\UpdateTableBuffer.p(input BUFFER orderdtl:Handle, ‘Number19’, NetPrice).

There is no converting for that, you have to write it. What updatetablebuffer did was save a change to the table.

1 Like

Thank you.

As mentioned I am very very new to BPM ABL and trying to convert E9 to E10 but ran into issues. With help, I have been able to convert a few, but still running into issues. For example:

for each OrderDtl no-lock where OrderDtl.Company = cur-comp and OrderDtl.OrderNum = orderNum .
assign NetPrice = OrderDtl.DocUnitPrice * ( 1 - (OrderDtl.DiscountPercent / 100 ))
ExtPrice = OrderDtl.SellingQuantity * OrderDtl.DocUnitPrice * ( 1 - OrderDtl.DiscountPercent / 100 ) .
end.

If I have this code, how would this be converted seeing I have no idea where cur-comp & orderNum are coming from. Are they system generated variables or what? I do not know how would I make the C# code especially not knowing.

Help anyone! Please!