Change Resource Group ID for Open Jobs

This is a stripped down version of our change resource group that works. Our resources are generic 9 characters with the first 6 the resource group, so the ressourcetimeused setting you will have to work out.UpdateResourceID v2.baq (40.0 KB)

2 Likes

Down the rabbit hole we go!

This is excellent! Thank you so much, Greg!

I have modified the code just a bit for my POC test. This work perfectly to update the ResourceGroupID, and Descriptions. I will get the entire thing working and post back with my final results. I can’t thank you all enough for persevering through this with me!
:heart:

/* update JobOpDtl */
string NewResourceGroup = string.Empty;
string NewResourceID = string.Empty;
string rgdesc = string.Empty;
Erp.Tables.JobOpDtl JobOpDtl;
Erp.Tables.JobOper JobOper;
Erp.Tables.ResourceGroup ResourceGroup;
Erp.Tables.ResourceTimeUsed ResourceTimeUsed;
foreach (var ttResults_iterator in (from ttResults_Row in ttResults
                                    where !ttResults_Row.Unchanged()
                                    select ttResults_Row))
{
    var ttResultsRow = ttResults_iterator;
    JobOpDtl = (from JobOpDtl_Row in Db.JobOpDtl
               where JobOpDtl_Row.Company == Session.CompanyID && JobOpDtl_Row.SysRowID == ttResultsRow.JobOpDtl_SysRowID
               select JobOpDtl_Row).FirstOrDefault();
    if (JobOpDtl != null)
    {
      NewResourceGroup = ttResultsRow.JobOpDtl_ResourceGrpID;
      NewResourceID = ttResultsRow.JobOpDtl_ResourceID;
	  ResourceGroup = (from ResourceGroup_Row in Db.ResourceGroup
                             where ResourceGroup_Row.Company == Session.CompanyID  && ResourceGroup_Row.ResourceGrpID == NewResourceGroup &&
                             (ResourceGroup_Row.Inactive != true)
                             select ResourceGroup_Row).FirstOrDefault();
            if (ResourceGroup != null)
            {
                rgdesc = ResourceGroup.Description;
            }
      
        Ice.Diagnostics.Log.WriteEntry("New RG is " + ttResultsRow.JobOpDtl_ResourceGrpID);
    
        JobOpDtl.ResourceGrpID = NewResourceGroup;
        JobOpDtl.OpDtlDesc = rgdesc;
        

        foreach (var ResourceTimeUsed_iterator in (from ResourceTimeUsed_Row in Db.ResourceTimeUsed
                                                        where ResourceTimeUsed_Row.Company == JobOpDtl.Company
                                                        && ResourceTimeUsed_Row.JobNum == JobOpDtl.JobNum
                                                        && ResourceTimeUsed_Row.AssemblySeq == JobOpDtl.AssemblySeq
                                                        && ResourceTimeUsed_Row.OprSeq == JobOpDtl.OprSeq
                                                        && ResourceTimeUsed_Row.OpDtlSeq == JobOpDtl.OpDtlSeq
                                                        select ResourceTimeUsed_Row))
                    {
                        ResourceTimeUsed = ResourceTimeUsed_iterator;
                        Ice.Diagnostics.Log.WriteEntry(" made it to resourcetimeused " + ResourceTimeUsed.OprSeq);
                        ResourceTimeUsed.ResourceGrpID = ttResultsRow.JobOpDtl_ResourceGrpID;
                     
                        ResourceTimeUsed.ResourceID = NewResourceID;
                    }
		foreach (var JobOper_iterator in (from JobOper_Row in Db.JobOper
                                                        where JobOper_Row.Company == JobOpDtl.Company
                                                        && JobOper_Row.JobNum == JobOpDtl.JobNum
                                                        && JobOper_Row.AssemblySeq == JobOpDtl.AssemblySeq
                                                        && JobOper_Row.OprSeq == JobOpDtl.OprSeq
                                                        select JobOper_Row))
                    {
                        JobOper = JobOper_iterator;
                        Ice.Diagnostics.Log.WriteEntry(" made it to JobOper " + JobOper.OprSeq);           
                        JobOper.OpDesc = rgdesc;
                    }
     
       
    }
}

I have the BAQ working perfectly now. When I run it in the BAQ screen, the custom action executes and returns the message showing how many records have been updated.

However, when I try to run the same thing in my customized dashboard, the action runs and the messages shows that no records have been updated. I can’t understand why. I thought maybe the callcontextBPMData part was wrong. So I hard coded the value instead of passing through call context. The action completes but does not process any of my records.

Here is the code in my BPM (thanks so much to @gpayne for getting this part cleared up.): You can see in here where I commented out the callcontext and hardcoded the values.

/* update JobOpDtl */

string NewResourceID = string.Empty;
string rgdesc = string.Empty;
Erp.Tables.JobOpDtl JobOpDtl;
Erp.Tables.JobOper JobOper;
Erp.Tables.ResourceGroup ResourceGroup;
Erp.Tables.Resource Resource;
Erp.Tables.ResourceTimeUsed ResourceTimeUsed;
foreach (var ttResults_iterator in (from ttResults_Row in ttResults
                                    where ttResults_Row.Unchanged()
                                    select ttResults_Row)) // for every line in the BAQ results do this stuff...
{
    myCount=myCount+1;
    var ttResultsRow = ttResults_iterator;
    JobOpDtl = (from JobOpDtl_Row in Db.JobOpDtl
               where JobOpDtl_Row.Company == Session.CompanyID && JobOpDtl_Row.SysRowID == ttResultsRow.JobOpDtl_SysRowID
               select JobOpDtl_Row).FirstOrDefault(); //Get the JobOpDtl record to update...
    if (JobOpDtl != null)
    {
      
    ResourceGroup = (from ResourceGroup_Row in Db.ResourceGroup
                             where ResourceGroup_Row.Company == Session.CompanyID  && ResourceGroup_Row.ResourceGrpID == "4AAA" && //callContextBpmData.ShortChar01 &&
                             (ResourceGroup_Row.Inactive != true)
                             select ResourceGroup_Row).FirstOrDefault(); //Get the resource group description
            if (ResourceGroup != null)
            {
                rgdesc = ResourceGroup.Description;
            }
    Resource = (from Resource_Row in Db.Resource
                             where Resource_Row.Company == Session.CompanyID  && Resource_Row.ResourceGrpID == "4AAA" &&//callContextBpmData.ShortChar01 &&
                             (Resource_Row.Inactive != true)
                             select Resource_Row).FirstOrDefault(); //Get the resource ID
            if (Resource != null)
            {
                NewResourceID = Resource.ResourceID;
            }
      
        Ice.Diagnostics.Log.WriteEntry("New RG is " + "4AAA");//callContextBpmData.ShortChar01);
    
        JobOpDtl.ResourceGrpID = "4AAA";//callContextBpmData.ShortChar01; //Update the ResourceGRoupID and description
        JobOpDtl.OpDtlDesc = rgdesc;
        

        foreach (var ResourceTimeUsed_iterator in (from ResourceTimeUsed_Row in Db.ResourceTimeUsed
                                                        where ResourceTimeUsed_Row.Company == JobOpDtl.Company
                                                        && ResourceTimeUsed_Row.JobNum == JobOpDtl.JobNum
                                                        && ResourceTimeUsed_Row.AssemblySeq == JobOpDtl.AssemblySeq
                                                        && ResourceTimeUsed_Row.OprSeq == JobOpDtl.OprSeq
                                                        && ResourceTimeUsed_Row.OpDtlSeq == JobOpDtl.OpDtlSeq
                                                        select ResourceTimeUsed_Row)) //For each of the matching resourcetimeused rows do this stuff...
                    {
                        ResourceTimeUsed = ResourceTimeUsed_iterator;
                        Ice.Diagnostics.Log.WriteEntry(" made it to resourcetimeused " + ResourceTimeUsed.OprSeq);
                        ResourceTimeUsed.ResourceGrpID = "4AAA";//callContextBpmData.ShortChar01; //Update resourcetimeused groupID
                        ResourceTimeUsed.ResourceID = NewResourceID; //Update resourcetimeused resourceID
                    }
    foreach (var JobOper_iterator in (from JobOper_Row in Db.JobOper
                                                        where JobOper_Row.Company == JobOpDtl.Company
                                                        && JobOper_Row.JobNum == JobOpDtl.JobNum
                                                        && JobOper_Row.AssemblySeq == JobOpDtl.AssemblySeq
                                                        && JobOper_Row.OprSeq == JobOpDtl.OprSeq
                                                        select JobOper_Row)) //For each of the matching joboper rows do this stuff...
                    {
                        JobOper = JobOper_iterator;
                        Ice.Diagnostics.Log.WriteEntry(" made it to JobOper " + JobOper.OprSeq);           
                        JobOper.OpDesc = rgdesc; // Update operation description
                    }
     
       
    }
}

And here is the code inside my customized dashboard: Button 2 is the one that executes the action. I know that it does execute it because the messagebox in my action comes up at the end.

private void epiButtonC1_Click(object sender, System.EventArgs args)
	{
	// ** Place Event Handling Code Here **
		// Make sure old ID text field is populated
		if (String.IsNullOrEmpty(epiTextBoxC1.Text) == true)
		{
			 MessageBox.Show("Please enter an old Resource Group ID.");
			 return;
		}	
	LoadMyBAQwParam("ChangeOpenJobResGrpIDs", epiUltraGridC1, "OldResGrpID", epiTextBoxC1.Text);
	}

	private void epiButtonC2_Click(object sender, System.EventArgs args)
	{
		// ** Place Event Handling Code Here **
		// Make sure New ID text field is populated
		if (String.IsNullOrEmpty(epiTextBoxC2.Text) == true)
		{
			 MessageBox.Show("Please enter a new Resource Group ID.");
			 return;
		}

		// set callcontextbpmdata fields to textbox values
		EpiDataView edvCallContextBpmData = ((EpiDataView)(this.oTrans.EpiDataViews["CallContextBpmData"]));
		System.Data.DataRow edvCallContextBpmDataRow = edvCallContextBpmData.CurrentDataRow;
		edvCallContextBpmDataRow["ShortChar01"] = epiTextBoxC2.Text;

		// Run custom code to change resource group ID for open jobs from old to new res grp id
		// Run custom code to update op description and res grp description to new description

		var edv = oTrans.Factory("V_ChangeOpenJobResGrpIDs_1View");
		BAQRunCustomAction(edv, "ChangeResGrpID");
		LoadMyBAQwParam("ChangeOpenJobResGrpIDs", epiUltraGridC1, "OldResGrpID", epiTextBoxC1.Text);

	}
	
private void BAQRunCustomAction(EpiDataView iEdv, string iActionID)
{
    BAQDataView BAQView = (BAQDataView)iEdv;
    Assembly assembly = Assembly.LoadFrom("Ice.Lib.EpiClientLib.dll");
    Type t = assembly.GetType("Ice.Lib.Framework.BAQUpdater");
    BindingFlags bf = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy;
    MethodInfo mi = t.GetMethod("BAQRunCustomAction", bf);
    object[] param = new object[] { BAQView, iActionID};
    mi.Invoke("Ice.Lib.Framework.BAQUpdater", param);
}


private void LoadMyBAQwParam(string myBAQ, EpiUltraGrid myGrid, string Param1ID, string Param1Val)
	{
	DynamicQueryAdapter yourbaq = new DynamicQueryAdapter(this.oTrans);
	yourbaq.BOConnect();
	Ice.BO.QueryExecutionDataSet dsBAQ = yourbaq.GetQueryExecutionParametersByID(myBAQ);
	dsBAQ.ExecutionParameter[0].ParameterID = Param1ID;
	dsBAQ.ExecutionParameter[0].IsEmpty = false;
	dsBAQ.ExecutionParameter[0].ParameterValue = Param1Val;
	dsBAQ.AcceptChanges();
	yourbaq.ExecuteByID(myBAQ, dsBAQ);
	myGrid.DataSource = yourbaq.QueryResults;
	yourbaq.Dispose();
	} 

I can’t see any reason why my action would work in BAQ and not in the dashboard. Can you see any reason?
Thanks!
Nate

Could it be that ttResults is only populated for the BAQ view? Do I have to populate ttResults differently when I run from a Dashboard?

I does something different, but I can’t remember the exact details. I seem to remember the the BAQ returned 1 row per, but the dashboard would return the previous and updated row, so it would get double the rows if you didn’t filter it right in the BPM. But that seems opposite of what your seeing.

Could it be changing it, then changing it back?

It is still ttResults. I have never done this with a form. I simply type the new data in the grid and click save. The update runs just like it does in the BAQ.

It doesn’t seem to be changing anything. This is my messagebox.

Updated <myCount/> records!
callcontext: <callContextBpmData.ShortChar01/>
var: <NewResGrpID/>
action id: <actionID/>

You can see myCount is increased as the first line in the foreach of ttResults.

When I run in BAQ I get “Updated x records!” But in the dash view it says “Updated 0 records!”

I can’t point to form elements from a BPM custom code widget, right? I know that my epiUltraGridC1 called “V_ChangeOpenJobResGrpIDs_1View” contains the results of my BAQ. Can I somehow point to that instead of ttResults?

If it’s a one time thing, can’t you just run it from the BAQ?

Perhaps I could get away with this. It would certainly be a workaround, but I feel like we are so close to the end here, I would hate to give up now!

I think the code I used from @josecgomez for executing the custom action might be the problem.

While the code does execute the custom action, it seems to do so on an empty ttResults table.

private void BAQRunCustomAction(EpiDataView iEdv, string iActionID)
{
    BAQDataView BAQView = (BAQDataView)iEdv;
    Assembly assembly = Assembly.LoadFrom("Ice.Lib.EpiClientLib.dll");
    Type t = assembly.GetType("Ice.Lib.Framework.BAQUpdater");
    BindingFlags bf = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy;
    MethodInfo mi = t.GetMethod("BAQRunCustomAction", bf);
    object[] param = new object[] { BAQView, iActionID};
    mi.Invoke("Ice.Lib.Framework.BAQUpdater", param);
}

I won’t pretend I understand exactly how this little function works.

Can you see anything that would let me pass in ttResults? (the current contents of the epiUltraGridC1 might work)

Edit: I think it may be because the BAQ needs the parameter passed in to populate the ttResults. When I click button 1 I pass the parameters in through the callcontextbpm data field (pulled form the textbox). But when I execute the custom action I do not pass this parameter. This could be why ttResults is empty. How can I pass that parameter using the code above?

Well it does it on the dataview you pass in. So that dataview should contain the dataset you want to apply the changes to.
Custom actions require the results to already have been populated. That is the data passed in.

Do you have any idea why the ttResults table seems blank then?

Hmmm is the DataView you are passing actually a BAQResult which would match what the BAQ is expecting?

I see… hmm I wonder if you are having to pass a rowmod?

In your dashboard, does the custom actions not show up here?

Do you mean passing a rowmod inside my custom action code? Like in the where clause of the ttResults iterator?

No like passing in the “modified” Row that is the Row you need to / want to pass in. If that makes sense.

Just for :poop: and giggles. Can you remove the where clause from your loop once?

Or add another loop before it, just to get a count of the rows.

In the original it was !ttResults.UnChanged() as in it was changed. Now it is only looking for unchanged rows which are not passed into ttResults.

No. But I thought that was because I setup a blank dashboard with a blank tracker view. Then I added all my components manually.

I am not sure what you mean.

I actually did remove that where clause as I could tell it wasn’t needed. The BAQ processes correctly without it, but the change had no effect on the dashboard.

I think this worked for your example because you were manually clicking in the UBAQ and editing a value. I am passing in all values of the BAQ and stepping through each one to update the ResGrpIDs. I pulled the where out completely so that ALL rows of my BAQ would be processed. Does that make sense?

But why???

1 Like