BPM - From Sales Order Entry - Get opportunity quote -Create order from quote

I am invoking the “Get Opportunity Quote” from the Sales Order Screen. So, I am “creating order from a quote” and using that method which is part of the Sales Order Object.

Unfortunately, I do not know how to get access to the “quote” information using the BPM ( i.e. Sales order object - Erp.SalesOrder.CreateOrderFromQuote Method).

Is there any easy way to access the quote table BEFORE creating the sales order via a BPM?

The standard Method tables are all sales order information, not the quote that I am using to create the sales order.

I am just trying to compare fields from the quote BEFORE creating the sales order… just a reminder, this is creating a sales order from a quote on the SALES ORDER side… Not the quote side.

Thanks a bunch!

-Marty

We run custom code in a Data Directive BPM to grab values from custom fields in the QuoteDtl table and copy them to matching custom fields in the OrderDtl table when Orders are created. This code runs for each OrderLine where the QuoteNum > 0;

Erp.Tables.QuoteDtl QuoteDtl;
foreach (var ttOrderDtlRow in (from ttOrderDtl_Row in ttOrderDtl
                                     where ttOrderDtl_Row.RowMod == "A" && ttOrderDtl_Row.QuoteNum != 0
                                     select ttOrderDtl_Row))
{
    {
        foreach (var QuoteDtlRow in (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))
        {
            using (System.Transactions.TransactionScope txScope = IceDataContext.CreateDefaultTransactionScope())//start the transaction
            {
                    ttOrderDtlRow["CustomField1"] = (string)QuoteDtlRow["CustomField1"];
                    ttOrderDtlRow["CustomField2"] = (string)QuoteDtlRow["CustomField2"];
                    etc...

                    txScope.Complete(); //commit the transaction
            }
        }
    }
}

Just a comment about the code. You are setting up a txScope on a temporary (memory) table… I don’t believe that this is necessary, as it is already inside a base scope, since this (assuming) is inside an In-trans data directive.
What I was told was that you need to create a scope if it is reading and updating actual database records.

Another trick to improve performance is to eliminate the second “foreach” and fetch the data… also only include the fields that you NEED to have in the dataset inside the select. Here is revised (untested) code… hopefully i didnt leave out any parentheses. (I know… some of the formatting is personal preference)

Erp.Tables.QuoteDtl QuoteDtl;
foreach (var ttOrderDtlRow in (
	from ttOrderDtl_Row in ttOrderDtl where
    	ttOrderDtl_Row.RowMod == "A" && 
		ttOrderDtl_Row.QuoteNum != 0
    select ttOrderDtl_Row))
{
	var QuoteDtlRow = Db.QuoteDtl.Where(
		r =>r.Company == ttOrderDtlRow.Company && 
		r.QuoteNum == ttOrderDtlRow.QuoteNum && 
		r.QuoteLine == ttOrderDtlRow.QuoteLine).Select( r => new {r.CustomField1 r.CustomField2} ).FirstOrDefault();

	if (QuoteDtlRow != null)
	{
		ttOrderDtlRow.CustomField1 = QuoteDtlRow.CustomField1;
		ttOrderDtlRow.CustomField2 = QuoteDtlRow.CustomField2;
	}
}

Thanks Tim. This was code auto generated by the Epicor ABL converter when we moved over from E9 to E10. Coding is my second hobby for the company so I appreciate the lesson!

Since C# is totally different than ABL, many times the translation “Works” but is not the most efficient. I found that you could use the converter to get most of the syntax, but it was best to rewrite some of the lines… but in my early days of C#, I had to rely on the converter.