Custom Fields with user permissions on Part Maintenance

So a while back, we had two customization done to the Part Maintenance application.
1.) We had a custom field created called Engineer, shown in the image below.

Basically this field contains a drop down list of our Engineers that quote parts. When a new part is entered in Part Maintenance, the engineer who quoted the part is manually assigned using the drop down. The list of engineers is controlled by User Codes, shown in the image below.

2.) The second customization was to the Status drop down that defines a part as New, Developing, or Production status.

image

This field is also controlled by User Codes.

The thing about these fields and the customization done to them is that they were set up to only allow the ‘master’ (our Manufacturing Engineer responsible for entering methods) to set and modify these fields. NO one else can make changes to these fields and they are actually grayed out to everyone else. The issue is that at the time we only had one person who entered methods, so having one master was fine. However, now we have two people responsible for entering new parts and methods. So I need these fields to allow the master and another person to set/modify these fields. I know there is coding logic behind it somewhere checking the users credentials to see if it is equal the defined ‘master’, but I am not sure where this logic would be.

Does anyone have any thought of where to start looking? I need to modify the logic to read something like ‘if user is equal to Master or other specific user allow them to interact with fields’. Please Help!! :slight_smile:

Try Field Security Maintenance. That’s where you can set certain fields to full access, read-only, etc. on a user-by-user basis. It’s located in System Setup > Security Maintenance and you’ll need to be a Security Manager to access it.

2 Likes

They could have also created a new security group to use in addition to the field security maintenance (hopefully they did, easier to maintain). If this is the case you would just need to add whichever other users need access to that group via “User Account Security Maintenance” module.

I am setup as a Security Manager in the System. I followed your direction and I did notice on the Part_UD table for the custom field, the user I want to have access didn’t. I changed it to full, but that only gave them the ability to see the data in those fields on the part maintenance screen. The fields are still grayed out and they cannot interact with the drop down menu arrows. They do however have the ability to now see and make changes to the updateable dashboard for these fields. So we are getting closer. Any other ideas? Like I said they did make a customization to the Part Maintenance application itself, could this have logic behind it that could be causing them not to access those fields?

I didn’t see anything like this…

Can you post the customization? Or copy and paste all the code in a message?

That’s the thing… I don’t know how to access the customization code. Do I need to be in Developer mode to do that?

yes, turn on developer mode, open the form, if there is a customization associated with it you’ll be prompted to choose one. Should you see multiple ones available, you can reference Menu Maintenance to see which one is in use from the location you launched the form. Once the form is open, go to Tools at the top then customization. The code if any will be under the script tab.

Just want to start out by saying three quick things to those of you who are trying to help me with this.

  1. All of you rock
  2. Thank you so much for your help with this. I really really appreciate it.
  3. Sorry for the novel below.

Now back to the customization issue. I tried to break it down to make it easier to follow. Please let me know if you have questions. (I should note, if it was not already obvious, I did not write any of this code)

First Customization is for the Part Status:

Status Field Code #1: (Only the ‘master’ can set the field)

private void epicmbStatus_Enter(object sender, System.EventArgs args)
{
		EpiTextBox tbPart = (EpiTextBox)(csm.GetNativeControlReference("38e1671b-0c3f-4ab3-b8ab-95f26285f1d2"));
		EpiCombo cmbStatus = (EpiCombo)(csm.GetNativeControlReference("a7e02cab-ea1f-42a8-aeae-8ea2ed60aded"));
		string sStatus = Convert.ToString(cmbStatus.Text);
		string userID = session.UserID;
		string sMaster = ""; string sEngineer = "";
		getStatusSecurity(userID, out sMaster, out sEngineer);	

		//if(sEngineer != userID && sMaster != userID)
		//{
		//	MessageBox.Show("You are not authorized to update this field; you are not the manager and not an Engineer.");
		//	tbPart.Focus();
		//	cmbStatus.Enabled = false; //turn off for this user
		//
		if(sEngineer == userID)
		{
			if(sStatus == "D")
			{
				MessageBox.Show("Changing Status to 'P'.");
				edvPart.dataView[0]["ShortChar08"] = "P"; cmbStatus.Text = "P";
				edvPart.dataView[0]["StatusDate_c"] = DateTime.Today;
				tbPart.Focus();
				cmbStatus.Enabled = false; //turn off
			}
			else
			{
				MessageBox.Show("Engineers may only change a stat D to a P.");
				tbPart.Focus();
				cmbStatus.Enabled = false; //turn off
			}
		}

		//if(sEngineer == userID && sStatus != "D")
		//{
		//	MessageBox.Show("You are set up as an Engineer but may only update when the status = D");
		//	tbPart.Focus();
		//	cmbStatus.Enabled = false; // turn off as they should not have tried to change this status
		//}

		if(sMaster == userID)
		{MessageBox.Show("You are the mananger of this system and can change anything.");}

Status Field Code #2: (The ‘assigned engineer’ can change field from D to P. Also generates query)

private void epicmbStatus_Leave(object sender, System.EventArgs args)
{
	EpiTextBox tbPart = (EpiTextBox)(csm.GetNativeControlReference("38e1671b-0c3f-4ab3-b8ab-95f26285f1d2"));
	EpiCombo cmbStatus = (EpiCombo)(csm.GetNativeControlReference("a7e02cab-ea1f-42a8-aeae-8ea2ed60aded"));
	string sStatus = Convert.ToString(cmbStatus.Text);
	string userID = session.UserID; string sMaster = ""; string sEngineer = "";
	getStatusSecurity(userID, out sMaster, out sEngineer);

	// if Engineer than can change to a P only
	if(sEngineer == userID && sStatus != "P") // only the master is allowed to edit this field all others out
	{
		MessageBox.Show("You can only change the status to P."); // maybe force this?
		cmbStatus.Enabled = false;
	}
	// if is master and change to N then use first routine
	if(sMaster == userID && sStatus == "N")
	{
		//eval using query and throw up message box recommendation for Engineer.
		MessageBox.Show("Place current BAQ for N D counts here.");

		DynamicQueryAdapter dqa1 = new DynamicQueryAdapter(oTrans);
		dqa1.BOConnect();
		QueryExecutionDataSet qeds1 = dqa1.GetQueryExecutionParametersByID("PartStatusByEngineer");
		qeds1.ExecutionParameter.Clear();
		//qeds1.ExecutionParameter.AddExecutionParameterRow("MachineID", workstationID, "nvarchar", false, Guid.NewGuid(),"A"); //since we dont want any parms skip it
		dqa1.ExecuteByID("PartStatusByEngineer",qeds1);
		DataTable tblStatusByEngineer = dqa1.QueryResults.Tables["Results"];
		//loop through populate the message box with data
		string sMsg = ""; string sSaveEng = ""; int iSaveEng = 99999999;
		for(int i=0; i < tblStatusByEngineer.Rows.Count; i++)
		{
			if(Convert.ToString(tblStatusByEngineer.Rows[i][0]) != "")
			{
				sMsg = sMsg + tblStatusByEngineer.Rows[i][0] + "   N=" + tblStatusByEngineer.Rows[i][1] + "   D=" + tblStatusByEngineer.Rows[i][2] + "   total=" + tblStatusByEngineer.Rows[i][3];
				if(Convert.ToString(tblStatusByEngineer.Rows[i][0]) != "" && Convert.ToInt32(tblStatusByEngineer.Rows[i][3]) < iSaveEng)
				{ sSaveEng = Convert.ToString(tblStatusByEngineer.Rows[i][0]);
				  iSaveEng = Convert.ToInt32(tblStatusByEngineer.Rows[i][3]);}
				if(Convert.ToString(tblStatusByEngineer.Rows[i][0]) != "")
				{ sMsg = sMsg + Environment.NewLine;}
			}
		}
		MessageBox.Show(sMsg + Environment.NewLine + Environment.NewLine + "Assign this part to " + sSaveEng);
		//edvPart.dataView[0]["AssignedEngineer_c"] = sSaveEng;
	}
	
}

Second Customization is for the Part Engineer:

Engineer Field Code: (Only the ‘master’ can assign the engineer)
private void epicmbAssignedEngineer_Enter(object sender, System.EventArgs args)
{
EpiTextBox tbPart = (EpiTextBox)(csm.GetNativeControlReference(“38e1671b-0c3f-4ab3-b8ab-95f26285f1d2”));
EpiCombo cmbStatus = (EpiCombo)(csm.GetNativeControlReference(“a7e02cab-ea1f-42a8-aeae-8ea2ed60aded”));
string sStatus = Convert.ToString(cmbStatus.Text);
EpiCombo cmbEngineer = (EpiCombo)(csm.GetNativeControlReference(“9c770db2-e8ac-4397-991d-0aa79c6199c5”));
string userID = session.UserID; string sMaster = “”; string sEngineer = “”;
getStatusSecurity(userID, out sMaster, out sEngineer);
//MessageBox.Show(“sMaster:” + sMaster + " userID:" + userID);
if(sMaster != userID) // only the master is allowed to edit this field all others out
{
tbPart.Focus();
cmbEngineer.Enabled = false; //turn off the field they should not be here
}
}

My Assumption:
I noticed that there is this “getStatusSecurity(userID, out sMaster, out sEngineer)” line of code in all of the scripts shown above. I assume this line of code is to run another script that checks the users ID. I provided that script below. Now, I believe the “getStatusSecurity” is the code that I want to modify to accept the ‘CodeID = ‘master’’ and ‘CodeID = ‘lgist’’ (that is the other user). I am not sure if it is just as easy as adding "String exp = "CodeID = ‘master’ " || “CodeID = ‘lgist’ " ;”. However, I think by doing something like that, it should solve the issue for both the Status and Engineer. What do you think? Is this the route I need to go?

Status Security Code:

private void getStatusSecurity(string userID, out string sMaster,out string sEngineer)
{
	sMaster = ""; sEngineer = "";
	try
	{
		bool morePages = false;
		UserCodesAdapter userCodesBO = new UserCodesAdapter(this.oTrans);
		userCodesBO.BOConnect();
		int iPageSize = 0; int iAbsolutePageSize = 1; bool bMorePages = false;

		SearchOptions opts = new SearchOptions(SearchMode.AutoSearch);
		opts.NamedSearch.WhereClauses.Add("UDCodes", "CodeTypeID = 'AssEng'"); //get everything later filter
		System.Data.DataSet dsMC = userCodesBO.GetRows(opts, out bMorePages);

		string exp = "CodeID = 'master'";	
		DataRow[] drMaster = dsMC.Tables["UDCodes"].Select(exp, "CodeID ASC");
		sMaster = Convert.ToString(drMaster[0]["CodeDesc"]); //this is the master user id	

		string exp2 = "CodeID = '" + userID + "'";	
		DataRow[] drEngineer = dsMC.Tables["UDCodes"].Select(exp2, "CodeID ASC");
		sEngineer = "Not Authorized";	
		
		if(drEngineer.Length > 0)
		{sEngineer = Convert.ToString(drEngineer[0]["CodeID"]);} //this is the master user id
		userCodesBO.Dispose();
					
	} catch (System.Exception ex)
	{
		ExceptionBox.Show(ex);
	}

The way it’s currently set up, there can be only one user tied to the “master” CodeID (ID’s are always unique), so in it’s current form you wouldn’t be able to “add” a new master UD code unfortunately (but you can still just modify the code)

For a quick fix, I think you are on the right track with adding a conditional statement.
You could try adding the following in the getStatusSecurity method (assuming the username you want to give access to is “IGist”):

sMaster = Convert.ToString(drMaster[0]["CodeDesc"]); //add after this line, this is the master user id	
if(userID == "IGist"){
     sMaster = "IGist";
}

The solution would probably need to be tweaked regarding how it uses the UD codes to be more maintainable (and not have to edit the code every time there is an additional “master”).

That Worked!!! You are a super hero! Thank you so very much.

1 Like