Help debugging BPM Code

Still no dice…

I’m not committed to using a post-processing directive; if there’s an easier/more efficient way to accomplish this, I’m all for it.

try this in pre-process

//first split
var lines = sourceLines.Split(’~’);
string msg = lines.Count().ToString() + " : "+ sourceLines;
this.PublishInfoMessage(msg, Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual, "", "");
//only iterate over details that are in source lines
    foreach (var tt in ttQuoteDtl.Where(d => d.Added() || d.Updated() &&  lines.Contains(d.QuoteLine.ToString()))
        {
            //now we get the related quote dtls 
          msg = string.Format("Working on Q{0} L{1}",tt.QuoteNum,tt.QuoteLine);
          this.PublishInfoMessage(msg, Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual, "", ""); 
            var oq = Db.QuoteDtl.Where(p => p.Company == tt.Company && p.QuoteNum ==SourceQuote && p.QuoteLine == tt.QuoteLine).FirstOrDefault(); 

            if (oq != null) //if null, then either that dtl doesnt exist
            {
                tt.OrderQty = oq.OrderQty;
                tt.SellingExpectedQty = oq.SellingExpectedQty;
                msg = string.Format("Updating Q{0} L{1} -> EQ{2}  SQ{3}",tt.QuoteNum,tt.QuoteLine,tt.OrderQty,tt.SellingExpectedQty);
                this.PublishInfoMessage(msg, Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual, "", ""); 

            }
                        
        } //only update once all records are modified
        Db.Validate();
1 Like

Still not working :confused:

added some debugging lines above to trace execution

I get one message box…it has the correct line count and all of the selected lines (tilde separated), but the quantities are still zero.

I still have to convert one of my CopyLines BPMs… I think the source contains more than just line(s)…

See My Old ABL


// NEW TODO:
NewSourceQuoteLines = ((i == 1) ? sourceQuoteLines.Entry(i - 1, Ice.Constants.ListSeparator) : NewSourceQuoteLines + Ice.Constants.ListSeparator + sourceQuoteLines.Entry(i - 1, Ice.Constants.ListSeparator));
sourceQuote = Compatibility.Convert.ToInt32(sourceQuoteLines.Entry(i - 1, Ice.Constants.ListSeparator).Entry(1, '`'));
sourceLine = Compatibility.Convert.ToInt32(sourceQuoteLines.Entry(i - 1, Ice.Constants.ListSeparator).Entry(0, '`'));
// END TODO
                
DEFINE VARIABLE myArray AS CHARACTER EXTENT 30 FORMAT "X(30)".
DEFINE VARIABLE myLoopIndex AS INTEGER INIT 1 NO-UNDO.

DEFINE VARIABLE iNumEntries AS INTEGER NO-UNDO.
DEFINE VARIABLE iLoop AS INTEGER NO-UNDO.
DEF BUFFER bNewUD06 FOR UD06.

DEF VARIABLE sCurrentQuoteNum AS CHARACTER NO-UNDO.
DEF VARIABLE sCurrentQuoteLine AS CHARACTER NO-UNDO.

// Count How Many We are Copying
ASSIGN iNumEntries = NUM-ENTRIES(sourceQuoteLines, '~~').

message "sourceQuoteLines: " + sourceQuoteLines.

// Lets Determine All the Lines we have to work with, so we can find the NEWEST Lines
// since Epicors Line Numbering is not Sequential we cant just guess
// we have to count the QuoteDtl because the tt only has the newly added lines
for first ttQuoteDtl, each QuoteDtl WHERE QuoteDtl.QuoteNum = ttQuoteDtl.QuoteNum no-lock by QuoteDtl.QuoteLine.
	message "- QUOTEDTL FOUND: " + string(QuoteDtl.QuoteLine).
	myArray[myLoopIndex] = string(QuoteDtl.QuoteLine).
	myLoopIndex = myLoopIndex + 1.
end.

// Lets Loop through our Lines to be copied
DO iLoop = 1 TO iNumEntries:

		// Assign Some Vars
		assign sCurrentQuoteNum = ENTRY(2, ENTRY(iLoop, sourceQuoteLines, '~~'), '`').
		assign sCurrentQuoteLine = ENTRY(1, ENTRY(iLoop, sourceQuoteLines, '~~'), '`').

		// Check if the Line we are copying has a UD06
		FIND FIRST UD06 WHERE UD06.Key1 = sCurrentQuoteNum AND UD06.Key2 = sCurrentQuoteLine no-error.
		message "Checking for UD06".
		IF AVAILABLE UD06 THEN DO:
			CREATE bNewUD06.
			BUFFER-COPY UD06 EXCEPT sysrevid sysrowid to bNewUD06
			ASSIGN bNewUD06.Key1 = string(targetQuoteNum)
						 bNewUD06.Key2 = string( myArray[ (myLoopIndex - iNumEntries - 1) + iLoop] ).

		END.

END.

Hmm so we arent matching records. Remove:

&& lines.Contains(d.QuoteLine.ToString())

It should dupe all the lines.

Are you saying that Original Line 1 may not equal Duplicate Line 1?

Just to verify we are using this method right?
Erp.Quote.DuplicateQuote

That’s the one.

I just did it with WIDGETS ONLY… Actually was fairly easy. NO C# CODE REQUIRED! It takes THREE widgets. The beauty here is that SAAS, MTSaas, or anyone that doesnt know C# code can make this work.
This is POST PROCESSING on the Quote Duplicate Method.

  1. Widget 3:(Created FIRST to get the dataset) - we will run the Erp.Quote.UpdateExt BO Method with specified Parameters.
  2. Widget 1: Fill quote lines - this reads the TTQuoteDtl records, and also links back to the source quote, and populates a new TT created for this BPM
  3. Widget 2: Fill quote header - this gets the company and new quote number
    Here is the overall view:
    image

Here is Widget 3: - Note that bindings 1, 4, and 5 have variables… I chose to create NEW Variables. My new dataset for the quote is called “FixQ”

Widget 1: Fill Lines:


You also need to “display” some fields from this query so that we can use them to populate data.
image

Then you map the query to the FixQ.QuoteDtl record (Bind Automatically works)
image

Widget 2 is very similar to Widget 1 (but simpler), but we need the FixQ.QuoteHeader to have the company and quote number:
image


image

2 Likes

I just realized ONE potential flaw… this assumes that you are copying ALL the lines… if you skip one, then the line numbers between each are different…

export.bpm (39.0 KB)
Attached is the BPM Export for what I wrote…
Thank you for the Exercise. I have needed a good example of how to use Fill Table by Query to then update fields. This proved my case that it “can be done”.
I am still learning!

1 Like

This is exactly what I was trying to work around.

My original code, as inefficient as it was, worked flawlessly if the source quote had all of the lines intact but when there was a deleted line in the source quote, it threw an exception.

DuplicateQuote from my experience just has Convert.ToString(sourceQuote) and has nothing to do with Lines =).

well… that’s what I get for notepad coding I guess :stuck_out_tongue: There are no details to iterate bahaha

Well, the widget bpm won’t throw such an error, but it also will not work if the originating quote has missing line items.
It could be tweaked to match lines by part Number instead of line item, but that would fail if there are duplicate parts on a quote. What you really need is a significant line ID that doesn’t change when duplicating.
If source quote has lines 1,2,4,5 -the new quote will have lines 1,2,3,4, and the bpm I wrote like successfully work on lines 1&2, but line 3 will not get a quantity and the new line 4(originally line 5) will get the third lines data.
You have a challenge!

Instead of passing order lines to dupe, pass the SysRowID of the lines to dupe, then you can for sure find them again

2 Likes

SysRowID for the win!

Grabbed the SysRowID, dropped it into my LINQ query, bingo, bango…everything works.

Thanks to everyone that chimed in to help; it is much appreciated.

2 Likes

Great news! Congrats on the epicor victory.

1 Like