Epicor Time Clock: Automatically Clocking Employees Out At End Of Day

It happens to the best of us: 5 PM rolls around, and it completely slips your mind to clock out for the day. And if you are an Epicor shop, you’ve now got an open labor record potentially racking up job costs. You can’t clock in (because Epicor says you are clocked in already), and hopefully, you are thoughtful enough to let HR know how to correct your record. More often than not, though, HR is the one stuck with the unfortunate responsibility to monitor for these incidents and adjust them after asking you when you clocked out.

Can’t Epicor automatically clock people out? As of this writing, there isn’t anything built-into Epicor to auto adjust time clock out entries, but here is how you can do it by building on a few of the concepts we’ve documented in the knowledge base.

  1. We need to start with a task we can run on a regular schedule. Follow the steps here to get to the point where you have a recurring task set up that can run some C# code via a BPM.

  2. Now we are going to leverage this guide to utilize Business Object calls within a BPM. The rest of this guide assumes you’ve got an understanding of the write-up there so take the time to read up on it if you are not already familiar.

Ok, so now we are ready to write our C# code. In order to do an auto clock off you are going to need to reference 2 DLL: EmpBasic and Labor. Add those following the instructions from #2. Then here is the C# code we will use:

// Custom Code
///////////////////////////////////////////////////////////////////////////////
string company = Session.CompanyID;

// Define references to the Business Objects
var empBasic = ServiceRenderer.GetService<Erp.Contracts.EmpBasicSvcContract>(Db);
var labor = ServiceRenderer.GetService<Erp.Contracts.LaborSvcContract>(Db);

// Query for all active LaborHed records.  You could add an extra filter in 
// here to only include folks logged on beyond a certain number of hours
// here as well if you like.
var laborHeds = Db.LaborHed.Where(lh => lh.Company == company
                                     && lh.ActiveTrans);
List<string> empIds = new List<string>();

// Loop through each of the labor header records we found
foreach(var laborHed in laborHeds) {
  // Pull up the labor record using GetByID
  Erp.Tablesets.LaborTableset laborTs = labor.GetByID(laborHed.LaborHedSeq);
  
  int updates = 0;
  // Loop through all of the Labor Details that are also active.  For each one 
  // that we find, flip EndActivity to true and set RowMod to "U"
  foreach(var laborDtl in laborTs.LaborDtl.Where(ld => ld.ActiveTrans)) {
    laborDtl.EndActivity = true;
    laborDtl.RowMod = "U";
    updates++;
  }
     
  // If we updated more than 1 Labor Detail, save our changes using Update.
  if (updates > 0) {
    labor.Update(ref laborTs);
  }
  
  // Keep track of the employees we were able to clock out.
  empIds.Add(laborHed.EmployeeNum);
}

// Now loop through each employee and clock them out.
foreach(string empId in empIds) {
  string e = empId;
  empBasic.ClockOut(ref e);
}
    
///////////////////////////////////////////////////////////////////////////////

This code keeps things pretty simple - it just takes everybody that has a current labor record open, ends activity, and then clocks them out. The intent here would be to just run this once per day (say at 6 PM), but you can easily modify this to only clock out folks that have been clocked on for more than, say, 10 hours and schedule the code to run more frequently.

From here maybe you want to email HR (and maybe the employee) letting them know they were auto clocked out. You can find out how to do that here. And if you are looking for an improved time clock solution for Epicor that employs biometrics + RFID, head over here to read about our solution.

Hope this helps!