PO Box 1128 Yorktown Heights, NY 10598
+1 914-407-2442
+1 914-407-2432

How can I add a change log to Employee Entry?

I find it amazing that with the type of information stored in Employee Entry/Maintenance a change log is not available for that screen by default. Or is it…?  Of course, as with everything in Epicor, where there’s a will there’s a way, and in this case it’s not at all too bad! All of the following is as it relates to Epicor 9 but Epicor 10 would be very similar, if not the same.

First things first, we need to get the change log set up for the EmpBasic table. The process here is the same as any other change log (it varies depending on whether you’re using Epicor 9 or Epicor 10, but the result is the same).

  1. Enter “Business Activity Manager” under “System Management”
  2. Add a new record and use the table “EmpBasic”
  3. Save, then add your fields
  4. Create your new BAM Rule
  5. Save, Refresh (you’ll get that pesky “row has been modified” error if you click the Test button at this point without clicking Refresh before Test), click Test, then Save

Now the fun begins. How do we get the button in the toolbar in Employee Entry? Let’s start by adding the custom reference we will need here, allowing us access to launch the ChgLogEntry screen.

  • Tools → Assembly Reference Manager → Add Custom Reference → Select “Epicor.Mfg.AD.ChgLog”

Next, in order to access the objects required to add the button back in and manipulate the toolbar, we should add a using statement.

using Infragistics.Win.UltraWinToolbars;

Next, we’ll create our module level variables. We need the EmpBasic dataview, BaseToolbarsManager, and one ButtonTool for our new button. We’ll initialize the code and variables we need, as well as set up the destroys for them. They can be set up by hand or you can use the Event Wizard to add the EpiViewNotification on EmpBasic and the ToolClick events. At any rate, it will look similar to below:

private EpiDataView edvEmpBasic;
private ButtonTool _btlChgLog;

public void InitializeCustomCode()
{
	this.edvEmpBasic = ((EpiDataView)(this.oTrans.EpiDataViews["EmpBasic"]));
	this.edvEmpBasic.EpiViewNotification += new EpiViewNotification(this.edvEmpBasic_EpiViewNotification); // We need this to control if the button is enabled or disabled
	this.baseToolbarsManager.ToolClick += new ToolClickEventHandler(this.baseToolbarsManager_ToolClick); // We need this so we can perform an action when the change log button we add is clicked
}

public void DestroyCustomCode()
{
	this.edvEmpBasic.EpiViewNotification -= new EpiViewNotification(this.edvEmpBasic_EpiViewNotification);
	this.edvEmpBasic = null;
	this.baseToolbarsManager.ToolClick -= new ToolClickEventHandler(this.baseToolbarsManager_ToolClick);
	_btlChgLog.Dispose();
	_btlChgLog = null;
}

Now! We finally get down to some dirty business. Let’s create a function that generates our new button if it does not exist or captures it in our _btlChgLog variable if it does. Why try and capture it? Well, in some screens the button might exist but has just been hidden by the developers.

private void AddChgLogButton()
{
	if (!baseToolbarsManager.Tools.Exists("ChangeLogTool")) // Here we check to see if the tool exists yet - "ChangeLogTool" is the standard name Epicor gives it
	{
		_btlChgLog = new ButtonTool("ChangeLogTool"); // Create the new tool and put it in our variable
		_btlChgLog.SharedProps.Caption = "Change Log...";
		_btlChgLog.SharedProps.Category = "Actions";
		EmpBasicEntryForm.setToolImage(_btlChgLog, "ChangeLog"); // This will add the book change log image to the button - you can find the list of names for icons by using the Epicor Resource Editor and opening the MfgBaseImages.resources file from the Client/res execution directory
		baseToolbarsManager.Tools.Add(_btlChgLog); // This will add our new button to the toolbar
	}
	else
	{
		_btlChgLog = (ButtonTool)baseToolbarsManager.Tools["ChangeLogTool"];
	}
		
	_btlChgLog.SharedProps.Visible = true; // In all cases we want to ensure the button is visible
}

Now that we have our function to add the button, either by hand or using the wizard, create the form_load method for this screen and add our method we just created there.

private void EmpBasicEntryForm_Load(object sender, EventArgs args)
{
	AddChgLogButton();
}

Last but not least, we will use the EpiViewNotify and ToolClick events to finish off this bad boy. Again this will control if the button is enabled or disabled and what it will do when clicked.

private void edvEmpBasic_EpiViewNotification(EpiDataView view, EpiNotifyArgs args)
{
	if ((args.NotifyType == EpiTransaction.NotifyType.Initialize))
	{
		if ((args.Row > -1)) // Do we have a valid active row? If so enable our button, otherwise disable
		{
			_btlChgLog.SharedProps.Enabled = true;
		}
		else
		{
			_btlChgLog.SharedProps.Enabled = false;
		}
	}
}

private void baseToolbarsManager_ToolClick(object sender, ToolClickEventArgs args)
{
	if (args.Tool.Key == "ChangeLogTool") // This method will fire for all tools clicked so we put this "if" here to capture the button we want and perform an action
	{
		if (edvEmpBasic.Row > -1)
		{
			Epicor.Mfg.UI.App.ChgLogEntry.ChgLogArgs lfo  = new Epicor.Mfg.UI.App.ChgLogEntry.ChgLogArgs("EmpBasic", edvEmpBasic.dataView[edvEmpBasic.Row]["RowIdent"].ToString(), true); // Let's evaluate this outside the code view... continue reading...
			ProcessCaller.LaunchForm(oTrans, "Epicor.Mfg.UI.ChgLogEntry", lfo); // Launch the Change Log screen and behold the awesome
		}
		else
		{
			args.Tool.SharedProps.Enabled = false; // If, for some (unlikely) reason, we get here in the tool click and there is no active record, just disable the button
		}				
	}
}

So what was this gibberish up here: ChgLogArgs(“EmpBasic”, edvEmpBasic.dataView[edvEmpBasic.Row][“RowIdent”].ToString(), true);? Let’s look at each parameter.

  1. The first argument is simply the name of the database table we want to launch the screen for, the same as found in BAM entry
  2. The second argument is our current employee’s unique identifier for the dataview you might say. This holds the information required to retrieve change log items specific to this employee
  3. The third argument is whether or not we want the screen to be modal – that is your call

Well… that about wraps it up for this one. Here is all of the code end-to-end: (Disclaimer: This won’t just automagically work if you copy and paste it in, but you are welcome to try anyways.)

using Infragistics.Win.UltraWinToolbars;

public class Script {
    private EpiDataView edvEmpBasic;
    private ButtonTool _btlChgLog;

    public void InitializeCustomCode()
    {
        this.edvEmpBasic = ((EpiDataView)(this.oTrans.EpiDataViews["EmpBasic"]));
        this.edvEmpBasic.EpiViewNotification += new EpiViewNotification(this.edvEmpBasic_EpiViewNotification);
        this.baseToolbarsManager.ToolClick += new ToolClickEventHandler(this.baseToolbarsManager_ToolClick);
    }

    public void DestroyCustomCode()
    {
        this.edvEmpBasic.EpiViewNotification -= new EpiViewNotification(this.edvEmpBasic_EpiViewNotification);
        this.edvEmpBasic = null;
        this.baseToolbarsManager.ToolClick -= new ToolClickEventHandler(this.baseToolbarsManager_ToolClick);
        _btlChgLog.Dispose();
        _btlChgLog = null;
    }

    private void AddChgLogButton()
    {
        if (!baseToolbarsManager.Tools.Exists("ChangeLogTool")) 
        {
            _btlChgLog = new ButtonTool("ChangeLogTool"); 
            _btlChgLog.SharedProps.Caption = "Change Log...";
            _btlChgLog.SharedProps.Category = "Actions";
            EmpBasicEntryForm.setToolImage(_btlChgLog, "ChangeLog"); 
            baseToolbarsManager.Tools.Add(_btlChgLog); 
        }
        else
        {
            _btlChgLog = (ButtonTool)baseToolbarsManager.Tools["ChangeLogTool"];
        }

        _btlChgLog.SharedProps.Visible = true;
    }

    private void EmpBasicEntryForm_Load(object sender, EventArgs args)
    {
        AddChgLogButton();
    }

    private void edvEmpBasic_EpiViewNotification(EpiDataView view, EpiNotifyArgs args)
    {
        if ((args.NotifyType == EpiTransaction.NotifyType.Initialize))
        {
            if ((args.Row > -1))
            {
                _btlChgLog.SharedProps.Enabled = true;
            }
            else
            {
                _btlChgLog.SharedProps.Enabled = false;
            }
        }
    }

    private void baseToolbarsManager_ToolClick(object sender, ToolClickEventArgs args)
    {
        if (args.Tool.Key == "ChangeLogTool") 
        {
            if (edvEmpBasic.Row > -1)
            {
                Epicor.Mfg.UI.App.ChgLogEntry.ChgLogArgs lfo = new Epicor.Mfg.UI.App.ChgLogEntry.ChgLogArgs("EmpBasic", edvEmpBasic.dataView[edvEmpBasic.Row]["RowIdent"].ToString(), true); 
                ProcessCaller.LaunchForm(oTrans, "Epicor.Mfg.UI.ChgLogEntry", lfo); 
            }
            else
            {
                args.Tool.SharedProps.Enabled = false;
            }
        }
    }
}

Related Posts

1 comment

I’ve tried using this code for the Price List Entry screen, but I am receiving the following error:

Error Detail
============
Object reference not set to an instance of an object.

Stack Trace
===========
at Script.edvPriceLst_EpiViewNotification(EpiDataView view, EpiNotifyArgs args)
at Epicor.Mfg.UI.FrameWork.EpiViewNotification.Invoke(EpiDataView view, EpiNotifyArgs args)
at Epicor.Mfg.UI.FrameWork.EpiDataView.OnEpiViewNotification(EpiNotifyArgs e)
at Epicor.Mfg.UI.FrameWork.EpiDataView.Notify(EpiNotifyArgs args)
at Epicor.Mfg.UI.FrameWork.EpiTransaction.NotifyAll()
at Epicor.Mfg.UI.FrameWork.EpiBaseForm.setupUIElements()

Any thoughts on what I’m missing? The BAM is already set up, and the change log does work, you just have to OK out of the error screen.

Leave a reply