Copy UD fields from Quote header to order header when converting quote to order

I’m thinking I’m missing something in the “Usings & References…” button, but don’t know what I should put in there.

Also, the orderNum variable is not set, so that is why I think I’m getting the other error that it does not exist in the current context.

C# is case sensitive, I’m guessing you have ERP.Tables… instead of Erp.Tables

correct, ordernum is not a variable in a data directive

You hit the nail on the head! I’m usually pretty good about syntax. Got me on that one.

So how does the orderNum know what its value should be? I still get the same error for that: “The name ‘orderNum’ does not exist in the current context” Also, my orderNum field is not purple like yours is…

the ttOrderDtl data table will contain the order number that is part of that data.

To reference it, you could use a field setter widget and a local BPM variable that you would create to set the local variable equal to the ttOrderDtl.OrderNum value. Then you could use it in your custom code.

Easier way is you could also just reference the ttOrderDtl.OrderNum value directly in your custom code to get the order num.

something like this

var orderRow = ttOrderDtl.FirstOrDefault();
if(orderRow!=null)
{
var orderNum = orderRow.OrderNum;
}

Keep in mind that data directives are really more like a sql table update trigger than a business object method. BO methods can contain variables that get passed into them but data directives are only passed the data that is trying to be updated.

I used your code update and had to set the var orderNum = 0; before your code and was able to get it to pass the syntax…now to actually test it. Thanks for all your help! It is greatly appreciated!

1 Like

So, my testing is a bust. It won’t actually copy from the UD field from the QuoteDtl to the OrderDtl. I noticed that you have a line commented out. Does the commenting need to be removed so that update line will process?

What’s your actual code look like?

Erp.Tables.OrderDtl OrderDtl;
Erp.Tables.QuoteDtl QuoteDtl;

int LineNum = 1;

var orderRow = ttOrderDtl.FirstOrDefault();
var orderNum = 0;
if (orderRow != null)
{
orderNum = orderRow.OrderNum;
}

if (orderNum != 0)
{
foreach (var QuoteDtl_iterator in (from QuoteDtl_Row in Db.QuoteDtl where QuoteDtl_Row.Company == Session.CompanyID && QuoteDtl_Row.QuoteNum == callContextBpmData.Number01 select QuoteDtl_Row))
{
QuoteDtl = QuoteDtl_iterator;
OrderDtl = (from OrderDtl_Row in Db.OrderDtl
where OrderDtl_Row.Company == Session.CompanyID &&
OrderDtl_Row.OrderNum == orderNum &&
OrderDtl_Row.OrderLine == LineNum
select OrderDtl_Row).FirstOrDefault();

if (OrderDtl != null)
{
  OrderDtl["MachineMake"] = QuoteDtl["MachineMake"];

  //Db.OrderDtl.Update(OrderDtl);      
  LineNum++;
}

}
}

Can you debug a little and try popping some message out at certain points? It’s hard to say where it’s failing. It might not even be getting to the point where you’re trying to update…

How do I add messages to show what it is doing? Just a message box saying that it processed this particular chunk of data?

string body = “Here I am”;
this.PublishInfoMessage(body,Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual, “OrderDtl”, “Update”);

And you can place these throughout the code and only change the body string message

It never makes it into the foreach loop. Why is the callContextBpmData.Number01 used for the QuoteNum? Is that actually the case or was that something specific to your scenario?

I was probaby setting ccNumber01 to the specific quote num outside of the custom code. But you’re saying it doesn’t get to the foreach loop which means that order num is still 0.

sorry I misread; you’re in the loop but ccNumber01 isn’t set. That’s why its not looping, because theres no join to any meaningful information if cc isn’t set.

How can I link the quotenum without using a cc field?

So, when testing, it gets past the "if (orderNum != 0) and then loops 3 times with my message just after the if, but before the foreach.

After additional testing and modifying my code, I have it where I can see that both of the fields show my test data, but after the Quote to Order wizard completes, it does not save the data to the OrderDtl field.
I made my modifications based on the following post:

Erp.Tables.OrderDtl OrderDtl;
Erp.Tables.QuoteDtl QuoteDtl;

var orderRow = ttOrderDtl.FirstOrDefault();

foreach (var QuoteDtl_iterator in (from QuoteDtl_Row in Db.QuoteDtl where QuoteDtl_Row.Company == orderRow.Company && QuoteDtl_Row.QuoteNum == orderRow.QuoteNum && QuoteDtl_Row.QuoteLine == orderRow.QuoteLine select QuoteDtl_Row))
{
foreach (var OrderDtl_iterator in (from OrderDtl_Row in Db.OrderDtl where OrderDtl_Row.Company == orderRow.Company && OrderDtl_Row.OrderNum == orderRow.OrderNum && OrderDtl_Row.OrderLine == orderRow.OrderLine select OrderDtl_Row))
{
string body = QuoteDtl_iterator.MachineMake.ToString();
this.PublishInfoMessage(body, Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual, “OrderDtl”, “Update”);

OrderDtl_iterator.MachineMake = QuoteDtl_iterator.MachineMake;

string body2 = OrderDtl_iterator.MachineMake.ToString();
this.PublishInfoMessage(body2, Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual, "OrderDtl", "Update");

}
}

Remember that my scenario was different; I was building mine off of a method directive that had access to the quote num (it was CreateSalesOrderFromQuote or somthing). Yours is a data directive on QuoteDtl., which is just monitoring when QuoteDtl gets updated. You’ll have to find a way to query the quote in question to return a quote num, but without knowing your specific business problem it’s a little hard to tell you.

1 Like

I finally had time to go back and test this out using the Method Directive for Quote.CreateOrder and it works beautifully! Here are some more details for anyone else that may need help getting it working:

Pre-Processing Directive:

Post-Processing Directive:
image

Post-Processing Directive Code:
Erp.Tables.OrderDtl OrderDtl;
Erp.Tables.QuoteDtl QuoteDtl;

int LineNum = 1;
if (orderNum != 0)
{
//The below 2 lines will help with debugging to make sure it is processing properly
//string body = “1 - An orderNum exists.”;
//this.PublishInfoMessage(body,Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual, “Quote”, “CreateOrder”);

foreach (var QuoteDtl_iterator in (from QuoteDtl_Row in Db.QuoteDtl where QuoteDtl_Row.Company == Session.CompanyID && QuoteDtl_Row.QuoteNum == callContextBpmData.Number01 select QuoteDtl_Row))
{
//The below 2 lines will help with debugging to make sure it is processing properly
//string body2 = “2 - Starting foreach section.”;
//this.PublishInfoMessage(body2,Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual, “Quote”, “CreateOrder”);

QuoteDtl = QuoteDtl_iterator;

OrderDtl = (from OrderDtl_Row in Db.OrderDtl where OrderDtl_Row.Company == Session.CompanyID && OrderDtl_Row.OrderNum == orderNum && OrderDtl_Row.OrderLine == LineNum select OrderDtl_Row).FirstOrDefault();

if (OrderDtl != null)
{
  //The below 2 lines will help with debugging to make sure it is processing properly
  //string body3 = "3 - OrderDtl is not null.";
  //this.PublishInfoMessage(body3,Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual, "Quote", "CreateOrder");

  OrderDtl["FieldName"] = QuoteDtl["FieldName"];
  //Db.OrderDtl.Update(OrderDtl);      
  LineNum++;
}

}
}

If I read the title - havent read the whole thread - you can do that with UD Field Maps, no need for BPM, if I recall there is a QuoteHed to OrderHed Mapping you can set.

Mine was for UD fields going from QuoteDtl to OrderDtl. Also, I am on 10.2.200.15 and I was not able to find any UD Field Map for Quote to Order of any kind. Maybe I missed it?

1 Like