BPM throws an error in 10.2.600.7 but was ok in 10.1.500.28

,

Hi everyone, we are in the process of upgrading our E10 and I am getting the error message below while testing from a BPM on DuplicateQuote. Can anyone point me in the right direction as to what might be causing this?
Best regards
Adrian

We would have to see the code, assuming there is code.

Here it is;

/* This code copies the Qtys and Price from the source quote lines to the destination quote lines
   during dupliucation of a quote.
   This version of the code uses an interger array to store the source lines and then sort them into numerical order.
   This was required because the standard select window shows the lines in reverse order by line number and the users have a habit
   of sorting this window prior to OK, which sent the source lines in the wrong order for the original code for this routine.
   In Epicor the source lines are always presented in reverse order to the routine however this does not affect the outcome.
   Adrian Mepham
   Version 2
   30/1/2019
	 Added the coding required to change the user who entered the quote from the source quote to the destination quote
	 02/10/2019
*/

string msg = "";
string srclins = sourceLines;
string user = "";
int srclen = srclins.Length;
int numentries = 0;
decimal ordqty = 0;
decimal expqty = 0;
int i = 0;
int sourceline  = 0;
int destline  = 0;
int arraycount = 0;



decimal thisprice  = 0;
int destQuote  = 0;
Erp.Tables.QuoteDtl QuoteDtl;
Erp.Tables.QuoteQty QuoteQty;
Erp.Tables.QuoteHed QuoteHed;

var ttQuoteHed_iterator = (from ttQuoteHed_Row in ttQuoteHed
                         where (ttQuoteHed_Row.RowMod == "")
                         select ttQuoteHed_Row).FirstOrDefault();


if (ttQuoteHed_iterator != null)
{
  destQuote = ttQuoteHed_iterator.QuoteNum;
}
//Check for NS paint text file on the server
string paintFilePath = @"\\\\wap-erp-01\\NsPaint\\Costed Lines\\" + sourceQuote.ToString() + ".txt";
bool nsPaintLines = System.IO.File.Exists(paintFilePath);
//If there is a file on the server, copy it
if (nsPaintLines == true)
{
	System.IO.File.Copy(paintFilePath, @"\\\\wap-erp-01\\NsPaint\\Costed Lines\\" + destQuote.ToString() + ".txt");
}

//msg = "This Quote " + destQuote.ToString() + " Source Quote " + sourceQuote.ToString() + " Source Lines " + sourceLines + "NS Paint " + nsPaintLines.ToString() + "User ID " + user;

//this.PublishInfoMessage(msg, Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual, "Quote", "DuplicateQuote");

// count the number of source lines sent to this routine
while (i < (srclen - 1))
{
 if (srclins.Substring(i,1) == "~")
 {
    numentries++;
 }
  i++;
} 
numentries++;
i = numentries;


//load the individula source line values into an array and then sort this array into numerical order

int[] scrlinesarray = new int[numentries] ;
while (i > 0)
{
  scrlinesarray[arraycount] = Convert.ToInt32(srclins.Split('~')[i-1]);
  arraycount++;
   i = i - 1;
}

Array.Sort(scrlinesarray);
  
i = 0;
  
// pick off each source line and match it to the new quotelines (now in ascending order numerically)
// copying in the  quantities and price

while (i < numentries)
{
    sourceline = Convert.ToInt32(scrlinesarray[i]);
    destline++;
    
    //msg = "thisline " + sourceline.ToString() + " destline " + destline.ToString();
    //this.PublishInfoMessage(msg, Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual, "Quote", "DuplicateQuote");

    // Find Source Line

		QuoteHed = (from QuoteHed_Row in Db.QuoteHed
                         where (QuoteHed_Row.Company == Session.CompanyID
                              && QuoteHed_Row.QuoteNum == destQuote)
                         select QuoteHed_Row).FirstOrDefault();

		if (QuoteHed != null)
    {
			QuoteHed["EnteredBy_c"] = Convert.ToString(callContextClient.CurrentUserId);
			QuoteHed["CopiedQuote_c"] = true;
			user = Convert.ToString(ttQuoteHed_iterator["EnteredBy_c"]);
		}

    QuoteDtl = (from QuoteDtl_Row in Db.QuoteDtl
                         where (QuoteDtl_Row.Company == Session.CompanyID
                              && QuoteDtl_Row.QuoteNum == sourceQuote
                              && QuoteDtl_Row.QuoteLine == sourceline)
                         select QuoteDtl_Row).FirstOrDefault();

    if (QuoteDtl != null)
    {
          ordqty = QuoteDtl.OrderQty;
          expqty = QuoteDtl.SellingExpectedQty;
          thisprice = 0;

          // now get the price


          QuoteQty = (from QuoteQty_Row in Db.QuoteQty
                 where (QuoteQty_Row.Company == Session.CompanyID
                    && QuoteQty_Row.QuoteNum == sourceQuote
                    && QuoteQty_Row.QuoteLine == sourceline
                    && QuoteQty_Row.QtyNum == 1 )
                    select QuoteQty_Row).FirstOrDefault();

          if (QuoteQty != null)
          {
              thisprice = QuoteQty.DocUnitPrice;
      
              QuoteDtl = (from QuoteDtl_Row in Db.QuoteDtl
                         where (QuoteDtl_Row.Company == Session.CompanyID
                              && QuoteDtl_Row.QuoteNum == destQuote
                              && QuoteDtl_Row.QuoteLine == destline)
                         select QuoteDtl_Row).FirstOrDefault();
              if (QuoteDtl != null)
              {
                  QuoteDtl.OrderQty = ordqty;
                  QuoteDtl.SellingExpectedQty = expqty;
              }

              QuoteQty = (from QuoteQty_Row in Db.QuoteQty
                         where (QuoteQty_Row.Company == Session.CompanyID
                              && QuoteQty_Row.QuoteNum == destQuote
                              && QuoteQty_Row.QuoteLine == destline
                              && QuoteQty_Row.QtyNum == 1 )
                         select QuoteQty_Row).FirstOrDefault();

              if (QuoteQty != null)
              {
                   QuoteQty.DocUnitPrice = thisprice;
              } 
           Db.Validate();
          }
    }

 i++;
}

The only thing I can think of is. Epicor always recommends you use a TransactionScope when you are modifying any Db tables (non temp). 10.1 ran EntityFramework 4 while 10.2 is on EntityFramework 6, it may now be enforced as best practice - hence throwing the error it didn’t before.

using (var txScope = IceDataContext.CreateDefaultTransactionScope())
{
  // your Db Stuff
  txScope.Complete();
  Db.Validate();
}
1 Like

Thanks @hkeric.wci, I will try that. Hopefully, it will clear it

Also Maybe

Thank you @hkeric.wci. It’s working now. Another drink I owe you!

Hello Adrian, I need to create this very same customization and am happy I found your solution. I am new to Epicor programming though. First - is this a method directive? I assume so. If so, is it pre or post processing? Also, have you made any changes to the code above? I was going to copy and paste it for our use.

Thanks

OK this seems to have worked perfectly! I just copied the code above into a Post Processing Method Directive for Quote.DuplicateQuote and it worked great.

Thanks!

Hi Jim,
Glad you found it useful. As you probably noticed there was some stuff in there that would not be of much use to you but the duplicating of quantities and prices works just fine.
Best of luck with all your future projects. You will find, as I do, this site is an invaluable resource.