# I killed a label tree & a BPM question

**URL:** <https://www.epiusers.help/t/i-killed-a-label-tree-a-bpm-question/52741>\
**Category:** Epicor ERP 10\
**Tags:** bpm\
**Created:** [February 18, 2019, 11:50pm UTC](https://www.epiusers.help/t/i-killed-a-label-tree-a-bpm-question/52741 "2019-02-18T23:50:13Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![nhutchins](https://www.epiusers.help/user_avatar/www.epiusers.help/nhutchins/32/108_2.png) [@nhutchins](https://www.epiusers.help/u/nhutchins)\
**Post date:** [February 18, 2019, 11:50pm UTC](https://www.epiusers.help/t/i-killed-a-label-tree-a-bpm-question/52741/1 "2019-02-18T23:50:13Z")

</div>

What do you do on a 3 day weekend? Apparently, I killed a label tree…

 ![lables](https://www.epiusers.help/uploads/default/original/2X/6/63aaeaec6ad872bbcec75db79e3e05bf30921d1e.jpeg)

With some pointers from [epiUser.Help](http://epiUser.Help) and @amurdock, I managed to get Bartender installed, setup and semi-functional. Still a work in progress, but happy with the status thus far.

I’ve managed to get correct labels, depending on PurchaseType, to print automatically when a receipt line is marked as received. Still, need to figure out a few things before implementing this is production, but it’s a start!

**BPM Question**  
Does anyone have any tricks/ideas/code snippets to find the next operation on a job? Meaning if a SubContracting operation is received, I want to display the next operation, assuming the SubCon op isn’t marked as final.

---

<div class="post-metadata">

**Author:** ![jeowings](https://www.epiusers.help/letter_avatar_proxy/v4/letter/j/b5ac83/32.png) [@jeowings](https://www.epiusers.help/u/jeowings)\
**Post date:** [February 19, 2019, 1:01am UTC](https://www.epiusers.help/t/i-killed-a-label-tree-a-bpm-question/52741/2 "2019-02-19T01:01:08Z")

</div>

Great job! You are well on your way.

Does your job have operations within an operation, or said different sub assembly operations that need to be evaluated?

\*\*Josh Owings \*\*| JR Automation

**ERP Applications Manager**

O: +1  
(864) 397-9193 | C: +1 (864) 884-6587

---

<div class="post-metadata">

**Author:** ![nhutchins](https://www.epiusers.help/user_avatar/www.epiusers.help/nhutchins/32/108_2.png) [@nhutchins](https://www.epiusers.help/u/nhutchins)\
**Post date:** [February 19, 2019, 12:32pm UTC](https://www.epiusers.help/t/i-killed-a-label-tree-a-bpm-question/52741/3 "2019-02-19T12:32:36Z")

</div>

This situation is relatively simple, I know there are more complicated situations I’ll need to program for as well, but small steps first.

The structure of the job looks like this:

- Op 10 - Cut
- Op 20 - Machine
- Op 30 - OV Plating (subcontracting on PO)
- Op 40 - Assembly

When the PO related to Op 30 is received, I need to be able to find the next Op (40) and print that on the label.

Two thoughts come to mind;

1. Find a programmatical way to find the next op; loop through the possible options CurrentOp +1, until a match is found.
2. Find a “NextOp” field in the database, that I’m not aware of, and yes I hunted a bit. I would think the scheduling engine & work queues would need that data.

Any help would be much appreciated.

---

<div class="post-metadata">

**Author:** ![rbucek](https://www.epiusers.help/user_avatar/www.epiusers.help/rbucek/32/28841_2.png) [@rbucek](https://www.epiusers.help/u/rbucek)\
**Post date:** [February 19, 2019, 12:37pm UTC](https://www.epiusers.help/t/i-killed-a-label-tree-a-bpm-question/52741/4 "2019-02-19T12:37:28Z")

</div>

I’ll have to dig around, I recall building a baq report to print a move ticket that printed out the next operation. It’s a relatively straight forward query.

---

<div class="post-metadata">

**Author:** ![ridgea](https://www.epiusers.help/user_avatar/www.epiusers.help/ridgea/32/45082_2.png) [@ridgea](https://www.epiusers.help/u/ridgea)\
**Post date:** [February 19, 2019, 2:05pm UTC](https://www.epiusers.help/t/i-killed-a-label-tree-a-bpm-question/52741/5 "2019-02-19T14:05:28Z")

</div>

> [@nhutchins](#):
>
> the database, that I’m not aware of, and yes I hunted a bit. I would think the scheduling engine & work queues would need that data.

We done this and utilised MTL Tags Report.

I use a setter in the BPM work flow to find the next op number for example:

(from row in Db.JobOper  
where row.Company == ttRcvDtlRow.Company  
&& row.JobNum == ttRcvDtlRow.JobNum  
&& row.AssemblySeq == ttRcvDtlRow.AssemblySeq  
&& row.OprSeq \> ttRcvDtlRow.JobSeq  
select row.OprSeq). FirstOrDefault()

Then push that into the report parameters.

I’m sure we modified the data definition here also to bind the MtlTags To Job Oper so we could extract the next operations op comments.

![WIP%20Tags](https://www.epiusers.help/uploads/default/original/2X/e/ea8fdb434699f1aa2fe3118ee0c3da9db09ecbcf.jpeg)

---

<div class="post-metadata">

**Author:** ![A.Baeisa](https://www.epiusers.help/user_avatar/www.epiusers.help/a.baeisa/32/8988_2.png) [@A.Baeisa](https://www.epiusers.help/u/A.Baeisa)\
**Post date:** [February 19, 2019, 2:28pm UTC](https://www.epiusers.help/t/i-killed-a-label-tree-a-bpm-question/52741/6 "2019-02-19T14:28:01Z")

</div>

Hi @nhutchins,  
not sure if there is a ‘NextOp’ filed within any BO, but my conventional programmatic way to find next operation is to do foreach loop within your table, add condition to exclude any operation seq. smaller than your tt JobOper.Oprseq., then compare each matched records to variable (declared to start with zero) with another condition to update it only if Oprseq\_iterator value is smaller than the saved variable value, and that is it, i remember some one asked about finding the final operation within JobOper table, and i have posted the code, cant find it now, but it is the same logical principle.

---

<div class="post-metadata">

**Author:** ![A.Baeisa](https://www.epiusers.help/user_avatar/www.epiusers.help/a.baeisa/32/8988_2.png) [@A.Baeisa](https://www.epiusers.help/u/A.Baeisa)\
**Post date:** [February 19, 2019, 2:31pm UTC](https://www.epiusers.help/t/i-killed-a-label-tree-a-bpm-question/52741/7 "2019-02-19T14:31:16Z")

</div>

your code will give you the first record found, not necessarily the Next operation in sequence.  
 ![image](https://epiusers.help/uploads/default/original/2X/4/4bff97210af87309b0243cec142479b0b56469f7.png)

---

<div class="post-metadata">

**Author:** ![ridgea](https://www.epiusers.help/user_avatar/www.epiusers.help/ridgea/32/45082_2.png) [@ridgea](https://www.epiusers.help/u/ridgea)\
**Post date:** [February 19, 2019, 2:43pm UTC](https://www.epiusers.help/t/i-killed-a-label-tree-a-bpm-question/52741/9 "2019-02-19T14:43:32Z")

</div>

Hi Al,

Indeed it will but the row above filters out all preceding operations prior to the current op being receipted in 😉 row.OprSeq \> ttRcvDtlRow.JobSeq

---

<div class="post-metadata">

**Author:** ![A.Baeisa](https://www.epiusers.help/user_avatar/www.epiusers.help/a.baeisa/32/8988_2.png) [@A.Baeisa](https://www.epiusers.help/u/A.Baeisa)\
**Post date:** [February 19, 2019, 2:48pm UTC](https://www.epiusers.help/t/i-killed-a-label-tree-a-bpm-question/52741/10 "2019-02-19T14:48:10Z")

</div>

i can see that, and that is why the code will call any operation from the rest, unless your routing has only one record after the tt current operation which is not always the case

---

<div class="post-metadata">

**Author:** ![ridgea](https://www.epiusers.help/user_avatar/www.epiusers.help/ridgea/32/45082_2.png) [@ridgea](https://www.epiusers.help/u/ridgea)\
**Post date:** [February 19, 2019, 2:55pm UTC](https://www.epiusers.help/t/i-killed-a-label-tree-a-bpm-question/52741/11 "2019-02-19T14:55:27Z")

</div>

> [@A.Baeisa](#):
>
> why the code will call

Indeed you are right but the FirstOfDefault statement after this selects the first Record returned.

On another note its a small world. I know a few guys from your company from a previous life 🙂

---

<div class="post-metadata">

**Author:** ![A.Baeisa](https://www.epiusers.help/user_avatar/www.epiusers.help/a.baeisa/32/8988_2.png) [@A.Baeisa](https://www.epiusers.help/u/A.Baeisa)\
**Post date:** [February 19, 2019, 3:00pm UTC](https://www.epiusers.help/t/i-killed-a-label-tree-a-bpm-question/52741/12 "2019-02-19T15:00:39Z")

</div>

with regards to the code, if you use foreach loop instead as i explained to Norman, it will get the right records in all cases

with regard to the last sentences, sorry, i am not following,

---

<div class="post-metadata">

**Author:** ![hmwillett](https://www.epiusers.help/user_avatar/www.epiusers.help/hmwillett/32/93207_2.png) [@hmwillett](https://www.epiusers.help/u/hmwillett)\
**Post date:** [February 19, 2019, 3:15pm UTC](https://www.epiusers.help/t/i-killed-a-label-tree-a-bpm-question/52741/13 "2019-02-19T15:15:03Z")

</div>

You could retrieve the results of the query into an array, then loop through the contents of the array, find your current op, then the next op (if exists) would be index + 1.

---

<div class="post-metadata">

**Author:** ![A.Baeisa](https://www.epiusers.help/user_avatar/www.epiusers.help/a.baeisa/32/8988_2.png) [@A.Baeisa](https://www.epiusers.help/u/A.Baeisa)\
**Post date:** [February 19, 2019, 3:34pm UTC](https://www.epiusers.help/t/i-killed-a-label-tree-a-bpm-question/52741/14 "2019-02-19T15:34:03Z")

</div>

i would like to see the code of assigning selected Epicor Db.Table.Filed to a defined array withing the BPM class, i have tried before with no luck, however could you explain what do you mean by indexing by +1, will it work when gap between operation sequence is more than 1

---

<div class="post-metadata">

**Author:** ![hmwillett](https://www.epiusers.help/user_avatar/www.epiusers.help/hmwillett/32/93207_2.png) [@hmwillett](https://www.epiusers.help/u/hmwillett)\
**Post date:** [February 19, 2019, 3:37pm UTC](https://www.epiusers.help/t/i-killed-a-label-tree-a-bpm-question/52741/15 "2019-02-19T15:37:59Z")

</div>

> [@A.Baeisa](#):
>
> will it work when gap between operation sequence is more than 1

Yes, because the index refers to the array and its contents, not the job sequence.  
I’ll see if I can dig up some code where I did that. Stand by.

```cs
var ttLaborDtlR = ttLaborDtl.FirstOrDefault(r=>r.Added() || r.Updated());

if( ttLaborDtlR != null )
{
  string job = (string)ttLaborDtlR.JobNum;
  int op = (int)ttLaborDtlR.OprSeq;
  int nextOp = 0;
  int ass = (int)ttLaborDtlR.AssemblySeq;

  //Get an ascending list of job operations
  int[] jobOps = (
    from j in Db.JobOper.With(LockHint.NoLock)
    where j.Company == Session.CompanyID &&
          j.JobNum == job &&
          j.AssemblySeq == ass
    orderby j.OprSeq
    select j.OprSeq).ToArray();    

  for( int i = 0; i < jobOps.Count(); i ++ )  
  {
    if( jobOps[i] == op )
    {
      int nextAvail = i + 1;
      
      if( nextAvail < jobOps.Count() ) //Check to see if the next index is real
        nextOp = jobOps[nextAvail];        
    }      
  }
  
  //Set the next operations 'PrevOpComp' to true
  foreach(var jobs in(
    from jo in Db.JobOper.With(LockHint.UpdLock)
    where jo.Company == Session.CompanyID && 
          jo.JobNum == job &&
          jo.AssemblySeq == ass &&
          jo.OprSeq == nextOp
    select new {jo}))
  using( var scope = IceDataContext.CreateDefaultTransactionScope() )
  {
    if( jobs.jo != null )
      jobs.jo["PrevOpComp_c"] = true;    

    scope.Complete();    
  }
}

```

---

<div class="post-metadata">

**Author:** ![nhutchins](https://www.epiusers.help/user_avatar/www.epiusers.help/nhutchins/32/108_2.png) [@nhutchins](https://www.epiusers.help/u/nhutchins)\
**Post date:** [February 19, 2019, 5:18pm UTC](https://www.epiusers.help/t/i-killed-a-label-tree-a-bpm-question/52741/17 "2019-02-19T17:18:53Z")

</div>

Thanks @hmwillett! I’ll give this code a shoot, when/if I ever get a free moment…

---

<div class="post-metadata">

**Author:** ![A.Baeisa](https://www.epiusers.help/user_avatar/www.epiusers.help/a.baeisa/32/8988_2.png) [@A.Baeisa](https://www.epiusers.help/u/A.Baeisa)\
**Post date:** [February 20, 2019, 9:40am UTC](https://www.epiusers.help/t/i-killed-a-label-tree-a-bpm-question/52741/18 "2019-02-20T09:40:23Z")

</div>

Good morning @nhutchins,  
many thanks to @hmwillett i found what i needed in terms of using Array structure within Epicor,

added this command to your code @ridgea if you interested,

```cs
int iNextAvailabJobOperOprSeq = 0;
var ttRcvDtl_xRow = (from ttRcvDtl_Row in ttRcvDtl
where ttRcvDtl_Row.Company == Session.CompanyID
select ttRcvDtl_Row).FirstOrDefault();
if(ttRcvDtl_xRow != null)
{
int[] list = (from JobOper_Row in Db.JobOper
where JobOper_Row.Company == ttRcvDtl_xRow.Company
&& JobOper_Row.JobNum == ttRcvDtl_xRow.JobNum
&& JobOper_Row.AssemblySeq == ttRcvDtl_xRow.AssemblySeq
&& JobOper_Row.OprSeq > ttRcvDtl_xRow.JobSeq 
select JobOper_Row.OprSeq).ToArray();

iNextAvailabJobOperOprSeq=list.Min();

PublishInfoMessage("Next Available Job Operation Sequence is:"+iNextAvailabJobOperOprSeq,Ice.Common.BusinessObjectMessageType.Error,Ice.Bpm.InfoMessageDisplayMode.Individual,"BO","BOMethod");
}

```

---

<div class="post-metadata">

**Author:** ![ridgea](https://www.epiusers.help/user_avatar/www.epiusers.help/ridgea/32/45082_2.png) [@ridgea](https://www.epiusers.help/u/ridgea)\
**Post date:** [February 20, 2019, 10:25am UTC](https://www.epiusers.help/t/i-killed-a-label-tree-a-bpm-question/52741/19 "2019-02-20T10:25:35Z")

</div>

Nice work @A.Baeisa

---

<div class="post-metadata">

**Author:** ![nhutchins](https://www.epiusers.help/user_avatar/www.epiusers.help/nhutchins/32/108_2.png) [@nhutchins](https://www.epiusers.help/u/nhutchins)\
**Post date:** [February 24, 2019, 8:02pm UTC](https://www.epiusers.help/t/i-killed-a-label-tree-a-bpm-question/52741/20 "2019-02-24T20:02:35Z")

</div>

This worked perfectly for me! Thank you both @hmwillett & @ridgea!
