Set callContextBpmData.Number01 to QuoteLine

Hi.
If I set callContextBpmData.Number01 to dsQuoteDtlRow.QuoteLine, the value of Number01 is 1, which is the first quote line.
And when the BPM is called, there is an business logic error said The table ds.QuoteDtl has more than one record.
So what should I use if I want to save all lines?
Thanks.

Post your code…

using(var txscope = IceDataContext.CreateDefaultTransactionScope())
{
var ttQuoteDtlResults = (from ttQuoteDtlRow in ttQuoteDtl
					where ttQuoteDtlRow.Company ==Session.CompanyID
                                          && (ttQuoteDtlRow.RowMod == "U")
					select ttQuoteDtlRow).FirstOrDefault();
           {
                 if (ttQuoteDtlResults != null)
                           {	
                              callContextBpmData.Number02 = ttQuoteDtlResults.QuoteLine;
                              callContextBpmData.ShortChar01 = ttQuoteDtlResults["ShortChar02"].ToString();
                              Db.Validate();
                          }
              }
              txscope.Complete();
}

I also try to use foreach().
One more question, does Epicor have something like List?

Instead of rows.FirstOrDefault(), you can use rows.ToList(), then use foreach(var row in rows.ToList()) to iterate through.

I’m not saying that will solve this problem, but that is C# / linq functionality here for ToList().

How can I define a new callContextBpmData.List01? I can’t convert number01 from Int to List.
if I still use Number01 the result would always have one value.
Because I want to use the list value in post-processing BPM. So that why I need find a container to carry all values I need.
Thanks

I see what you mean. I’m not sure that an int array is something that is easily augmented into BpmData because I have not done this. Can you convert each int to string, then concatenate them using a separator like | or ~, then assign them to callContextBpmData.Character01, and then parse them back out into an integer list in the BPM? Even though you may be able to pass a parameter to the server through another means, or augment the BpmDataset in some way, I’d probably use this method as it will rely on the system you already bought to take care of considerations with the callContext dataset.

If you have a constant set of numbers less than ten, I’d recommend using Number01, Number02, etc. If you care about keeping the data past this point in time, I would create actual fields using extended ud maintenance.

1 Like

Thank you! I am going to try charactor01. Anyway, I need to find a way that can contain all line numbers.
Thanks again.

I think you are thinking of the old ABL … ?ListArray? column type. This does not exist in SQL / C#. It is really just a child table or a collection type. To get the simple scenario you mentioned Joseph is correct - string concat them together.

character01 = string.Join(",", myValues);

where myValues is a collection

@xiaoting this is purely for educational purposes, the other answers here are more than enough and creating a comma separated list is plenty. But if you truly want to put an array or a List of integers into CallContextBPM you could do it with serialization. Serialization is a technique of turning an object into a stream of bytes (or a specific format) in order to preserve the state of the object.

In a BPM you can use XMLSerialization to accomplish this.

Simply create an array of ints as shown below, serialize them and assign the result to BPMData.Character01, then on the post processing directive you do the opposite and Deserialize the string back into an array.

Same thing can be done with a List, or almost any other object

//Pre-Processing
int[] myIntArray = new int[] { 1, 3, 4, 5, 6, 6, 7 };
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(myIntArray.GetType());
System.IO.StringWriter sw = new System.IO.StringWriter();
serializer.Serialize(sw, myIntArray);
callContextBpmData.Character01 = sw.ToString();
//Post-Processing
System.Xml.Serialization.XmlSerializer DeSerializer = new System.Xml.Serialization.XmlSerializer(typeof(int[]));
System.IO.StringReader sr = new System.IO.StringReader(callContextBpmData.Character01);
int[] myIntArray = (int[])serializer.Deserialize(sr);

I’ve used this technique in the past to pass a much more complex object from pre-proc to post-proc.

3 Likes

It’s what we use to send everything over the wire in WCF. SOAP and REST use interop to play nice with integrations but for point to point where E10 is on both sides, we pack all data into a byte[] and serialize/deserialize the objects.

2 Likes

Very nice guys. Some of my work relies on this, but I have not had to build it first hand thus far.

1 Like

i see in post processing that you are getting the data OUT of callContextBPMData.Character01, but I never see you put it there in the Pre-process… did you miss something, or am i missing it?

I’ve added the missing line now :slight_smile: thanks @timshuwy

hahaha… i figured that would be the line, but I knew it was missing something!

1 Like