Quote.DuplicateQuote Post-Processing BPM Help

I am trying to create a BPM that fires when duplicating a quote and then copies the source quote’s OrderQty to the new quote, but I am new to using custom code in BPMs.

If anyone cares to share some code snippets that would give me an idea of how this can be accomplished, it would be greatly appreciated. I am sure I can work through it, eventually, but I could use a little help getting there quicker.

So…here’s what I have been able to come up with; currently I’m just returning the source quote line and Qty in a MessageBox:

using (var txScope = IceContext.CreateDefaultTransactionScope())
{
for (int i = 0; i < callContextBpmData.Number02; i++)
{
foreach (var QuoteDtl_Recs in (from QuoteDtl_Row in Db.QuoteDtl
where QuoteDtl_Row.Company == Session.CompanyID && QuoteDtl_Row.QuoteNum == sourceQuote && QuoteDtl_Row.QuoteLine == i + 1
select QuoteDtl_Row))
{
string msg = string.Format(“Quote Line = {0}\rQuote Qty = {1}”,i + 1, QuoteDtl_Recs.OrderQty);
this.PublishInfoMessage(msg,Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual,“Quote”,“Duplicate”);
// = QuoteDtl_Recs.OrderQty;
}
}
Db.Validate();
txScope.Complete();
}

My question is now, how do I update the new Quote’s Qty with the values from the source quote?

Hey :slight_smile:

Maybe you could use something like this:
var dbqt = Db.QuoteDtl.Where(p => p.Company == yourvar.Company && p.QuoteNum == yourvar.QuoteNum).FirstOrDefault();

if(dbqt != null){
dbqt.OrderQty = yourQty;
}
Db.Validate();

I hope I understood your question :smile:

Greetings
Marlon

I think I need to use a foreach loop instead of FirstOrDefault()…maybe I didn’t explain what I’m trying to do properly or maybe I’m not familiar enough with LINQ…

Problem:
When Customer Service clicks “Actions -> Duplicate”, a new quote is created, but all of the line quantities on the new quote are zero. I am trying to create a BPM that will copy the quantity values from the sourceQuote to the new quote.

So far, I have been able to capture the sourceQuote number (sourceQuote param) and the sourceLine (BPM Data field callContextBpmData.Number02). Where I am having an issue is setting the new quantity in the new quote.

Ok maybe now i understood it…
I am using Erp.Quote.DuplicateQuote/Post-Processing:
First i am setting the BPM Data Field Character01 with the “BpmFunc.Replace(sourceLines, “~” ,”" )" expression. After that the custom Code executes:

foreach (var tt in ttQuoteDtl){

for(int i = 0; i < callContextBpmData.Character01.Length; i++ ){
	int t  = callContextBpmData.Character01[i]-'0';
	var dbqt = Db.QuoteDtl.Where(p => p.Company == tt.Company && p.QuoteNum == tt.QuoteNum && p.QuoteLine == i+1).FirstOrDefault();
	dbqt.OrderQty = Db.QuoteDtl.Where(m => m.Company == tt.Company && m.QuoteNum == sourceQuote && m.QuoteLine == t).Select(p => p.OrderQty).FirstOrDefault();
}

Db.Validate();

}

grafik

I tested it a bit and it seems to work quite good

Thank you for your help! I’d been working on this problem for too long.

This is maybe a long shot, but using the solution above I was able to use this BPM and get the order QTY’s and some other fields to copy over upon duplication. Our company utilizes sales kits on some quotes, once a sales kit is introduced to the quote the BPM returns an error. Attached below.

Since i’m not extremely code savvy, i’m wondering if anyone has solved this issue or has any suggestions on how to deal with sales kits using the above BPM expressions.

1 Like

Heyho
Are you sure

var dbqt = Db.QuoteDtl.Where(p => p.Company == tt.Company && p.QuoteNum == tt.QuoteNum && p.QuoteLine == i+1).FirstOrDefault();

is filled when trying to update? Try to recreate the “Where(p => p.Company == tt.Company && p.QuoteNum == tt.QuoteNum && p.QuoteLine == LineNumber” in a BAQ.

Did you change the code? If so, post it here ^^

Hi @Marlon, I’m actually on this project, update the quantity on duplicate quote. I was capable to update the quantity, but i had noticed that the price List and the Discount List are not updated, so, all the amounts are not updated too. My question, have you being through this issue ?

Hi Sabrina,
Im trying to populate the OrderQty’s when duplicating the quote from the source quote but im afraid the above solution does not work on my enviroment unlike it seems to have on others, ive copied the above word for word and added a ‘Show message’ in the middle to display ‘Character01’ but it appears this is where my BPM falls down as there is nothing displayed in the Information box hence the reason i beleive the code is right as it seems to have worked for many others but ‘BpmFunc.Replace(sourceLines, “~” ,"" )’ results nothing on my version of Epicor… any help would be very much appreciated!!! thanks in advance!

Hi Joe,
I ended up dropping the idea of ​​copying the quantity, since the price list and the discount list did not follow, and all the amounts in the database did not update, we really had to run an update on the moment to copy the quantity, but it turned out to be a big challenge to do so, so i just updated the price list. and the user only had to put the quantity manually, which automatically triggers the Update method and updates all the amounts. I can give you the code I made for that if you want.
otherwise, for the sourceLines, I did a split in the code, then I put the rows in an array, I ordered this array, and I traversed it with a FOR. you have to be careful, it may be that the user will just duplicate certain lines, and sometimes it selects the lines to copy in a random way, that’s why I sort the array, after that you have to copy the quantity from the correct row to the correct row.
try this :

if(sourceLines != "")

{
string [] Tableau_ParentQuoteLine_String = sourceLines.Split(’~’);
int intTran;
int[] Tableau_ParentQuoteLine_Int = Tableau_ParentQuoteLine_String.Select(int.Parse).ToArray();
Array.Sort(Tableau_ParentQuoteLine_Int);

for (int i = 0; i < Tableau_ParentQuoteLine_Int.Count(); i++)
{
  intTran = Tableau_ParentQuoteLine_Int[i];      
  var ParentLine =  Db.QuoteDtl.FirstOrDefault(p => p.Company == Session.CompanyID && p.QuoteNum == sourceQuote && p.QuoteLine == intTran);
    
  foreach (var tt in ttQuoteDtl)
  {  
    if(tt.QuoteLine == i + 1)
    {    
      var NewLine = Db.QuoteDtl.FirstOrDefault(p => p.Company == Session.CompanyID && p.QuoteNum == tt.QuoteNum && p.QuoteLine == i + 1);  

NewLine.Orderqty= ParentLine.Orderqty;
}
Db.Validate();
}
}}

1 Like

Hi Sabrina,

Thanks! I moved away from this a while as I was getting no-where fast but I am going to have another go at this and hopefully use what youve put above to help.

Thanks again, Joe