Can this be done with a BPM or is custom code required within the BPM, Progress was my jam and I’m still rather green regarding many epicor paradigms. Has anyone done this?
I haven’t done this specifically, but I’ve done a lot with MES and LaborDtl / JobOper tables. I’ve got some ideas on how to do it, but I’m not sure the best route. You’re wanting it to pre-populate the field in the UI when they select a job and Operation in MES End Activity, correct? Are you using classic MES or Kinetic?
We are on Kinetic 2024.1.7. And your summation is correct. It is part of our initiative to have as little interaction in MES from shop staff and the keyboard/mouse. Currently we are on an old version of Syteline (Progress) and everything is barcoded, etc. keyboard/mouse are not used in anyway other than QC requirements, which limits the manual transactions to one highly trained emp.
If you’re using the Kinetic form, I’m not familiar enough with MES to know which triggers you should use, but what I’d do is create a function and trigger it when a job and operation are selected for end activity. Pass the JobNum and OprSeq into an Epicor function that returns the decimal value for qty complete of the previous operation. You should be able to populate the UI field with the return value.
The function would be a pretty simple one:
// thisJob - Pass in JobNum as Parameter
// thisOpr - Pass in Current OprSeq as Parameter
int PrevOprSeq = Db.JobOper.Where( x => x.JobNum == thisJob && x.OprSeq < thisOpr ).Max( m => m.OprSeq );
// Return previous JobOper Qty Complete as Decimal
ReturnValue = Db.JobOper.Where( x => x.JobNum == thisJob && x.OprSeq == PrevOprSeq ).Select( s => s.QtyCompleted ).FirstOrDefault() ?? 0m;
I have this BPM running well at method directive → post processing.Method name is DefaultOperSeq.
I have this custom field called PreviousOperationCompletedQty_c at LaborDtl table. You can place this in your end activity form.
I have a process for First Article inspection in my company, you may should get rid of it from the below code.
Erp.Tables.FirstArt FirstArt;
Erp.Tables.FirstArt FirstArt1;
Erp.Tables.LaborDtl LaborDtl1;
Erp.Tables.JobAsmbl JobAsmbl;
Erp.Tables.JobOper JobOpDtl;
Erp.Tables.JobOper JobOper;
Erp.Tables.LaborDtl LaborDtl2;
Erp.Tables.LaborDtl LaborDtl;
string Company = “”;
decimal LaborQty = 0.0m;
decimal LaborQty1 = 0.0m;
decimal LaborQty2 = 0.0m;
int OperationSeq = 0;
int LaborSeqDtl = 0;
decimal ProductionQty = 0.0m;
decimal OperQty = 0.0m;
decimal FirstArtQty = 0.0m;
decimal FirstArtQty1 = 0.0m;
decimal RemainingFirstArtQty = 0.0m;
decimal JobFirstArtQty = 0.0m;
decimal CurrentlaborQty = 0.0m;
decimal PreOprLaborQty = 0.0m;
decimal CurPostedLaborQty = 0.0m;
decimal TotalCurrentLaborQty = 0.0m;
foreach (var ttLaborDtl_iterator in from ttLaborDtl_Row in ds.LaborDtl
where string.Equals(ttLaborDtl_Row.RowMod, IceRow.ROWSTATE_ADDED, StringComparison.OrdinalIgnoreCase) ||
string.Equals(ttLaborDtl_Row.RowMod, IceRow.ROWSTATE_UPDATED, StringComparison.OrdinalIgnoreCase)
select ttLaborDtl_Row)
{
var ttLaborDtlRow = ttLaborDtl_iterator;
Company = ttLaborDtlRow.Company;
RemainingFirstArtQty = Convert.ToDecimal(ttLaborDtlRow[“RemainingFAQ_c”]);
JobFirstArtQty = Convert.ToDecimal(ttLaborDtlRow[“FAQty_c”]);
if (ttLaborDtlRow.LaborType == "P" || ttLaborDtlRow.LaborType == "S")
{
JobOper = (from JobOper_Row in Db.JobOper
where string.Compare(JobOper_Row.Company, ttLaborDtlRow.Company, true) == 0 &&
JobOper_Row.JobNum == ttLaborDtlRow.JobNum &&
JobOper_Row.AssemblySeq == ttLaborDtlRow.AssemblySeq &&
JobOper_Row.OprSeq < ttLaborDtlRow.OprSeq &&
JobOper_Row.SubContract != true
orderby JobOper_Row.OprSeq descending
select JobOper_Row).FirstOrDefault();
if (JobOper != null)
{
foreach (var LaborDtl_iterator in from LaborDtl_Row in Db.LaborDtl
where LaborDtl_Row.Company == Company &&
LaborDtl_Row.JobNum == ttLaborDtlRow.JobNum &&
LaborDtl_Row.AssemblySeq == ttLaborDtlRow.AssemblySeq &&
LaborDtl_Row.OprSeq == JobOper.OprSeq &&
LaborDtl_Row.ReWork == false &&
LaborDtl_Row.LaborType == "P"
select LaborDtl_Row)
{
LaborDtl = LaborDtl_iterator;
PreOprLaborQty += LaborDtl.LaborQty;
}
foreach (var FirstArt_iterator in from FirstArt_Row in Db.FirstArt
where FirstArt_Row.Company == Company &&
FirstArt_Row.JobNum == ttLaborDtlRow.JobNum &&
FirstArt_Row.AssemblySeq == ttLaborDtlRow.AssemblySeq &&
FirstArt_Row.OprSeq == JobOper.OprSeq &&
FirstArt_Row.FAStatus == "A"
select FirstArt_Row)
{
FirstArt = FirstArt_iterator;
FirstArtQty += FirstArt.ExpectedQuantity;
}
foreach (var FirstArt1_iterator in from FirstArt1_Row in Db.FirstArt
where FirstArt1_Row.Company == Company &&
FirstArt1_Row.JobNum == ttLaborDtlRow.JobNum &&
FirstArt1_Row.AssemblySeq == ttLaborDtlRow.AssemblySeq &&
FirstArt1_Row.OprSeq == ttLaborDtlRow.OprSeq &&
FirstArt1_Row.FAStatus == "A"
select FirstArt1_Row)
{
FirstArt1 = FirstArt1_iterator;
FirstArtQty1 += FirstArt1.ExpectedQuantity;
}
foreach (var LaborDtl2_iterator in from LaborDtl2_Row in Db.LaborDtl
where LaborDtl2_Row.Company == Company &&
LaborDtl2_Row.JobNum == ttLaborDtlRow.JobNum &&
LaborDtl2_Row.AssemblySeq == ttLaborDtlRow.AssemblySeq &&
LaborDtl2_Row.OprSeq == ttLaborDtlRow.OprSeq &&
LaborDtl2_Row.ReWork == false &&
LaborDtl2_Row.LaborType == "P" &&
LaborDtl2_Row.SysRowID != ttLaborDtlRow.SysRowID
select LaborDtl2_Row)
{
LaborDtl2 = LaborDtl2_iterator;
CurPostedLaborQty += LaborDtl2.LaborQty;
}
ttLaborDtlRow["PreviousOperationCompleteQty_c"] = PreOprLaborQty + FirstArtQty - (CurPostedLaborQty + FirstArtQty1);
}
}}