I have a BAQ that is quite simple (code is below) which grabs the active labor transactions for anyone clocked in for more than 12 hours.
SELECT
[LaborHed].[EmployeeNum] AS [LaborHed_EmployeeNum] /* Employee Number */
,[EmpBasic].[Name] AS [EmpBasic_Name] /* Employee Name */
,[LaborHed].[ClockInDate] AS [LaborHed_ClockInDate] /* Recorded ClockInDate */
,[LaborHed].[ClockInTime] AS [LaborHed_ClockInTime] /* Recorded ClockInTime */
,[LaborHed].[DspClockInTime] AS [LaborHed_DspClockInTime] /* Displayed ClockInDate - This is just so I can include it in a report in a format that people can read */
,(DATEDIFF(HOUR, CONVERT(DATETIME, CONCAT(ClockInDate, ' ', DspClockInTime)), GETDATE())) AS [Calculated_HoursClockedIn] /* I am not sure if this is the best way to go about this, but it gets the job done. */
,(CAST(YEAR(LaborHed.ClockInDate) AS NVARCHAR(4))) as [Calculated_ClockInyear] /* See notes in the Conditional statement below */
FROM Erp.LaborHed AS LaborHed
INNER JOIN Erp.EmpBasic AS EmpBasic /* Link up the EmpBasic table to get the Employee Name */
ON LaborHed.Company = EmpBasic.Company
AND LaborHed.EmployeeNum = EmpBasic.EmpID
WHERE LaborHed.ClockOutTime = 0 /* I have no idea if this is required or not, as I would expect ActiveTrans = 0 would be sufficient */
AND LaborHed.ActiveTrans = 1 /* We only want Active Transactions */
AND DATEDIFF(HOUR, CONVERT(DATETIME, CONCAT(ClockInDate, ' ', DspClockInTime)), GETDATE()) >= 12 /* We only care about records that have been open for more than 12 hours */
AND YEAR(LaborHed.ClockInDate) >= 2024 /* We only care about labor from 2024 onwards, as there are hundreds (if not thousands) of invalid LaborHed records from years past */
The âclocked out at midnightâ is tricky because the ClockOutMinute and ClockOutTime fields in the database are set to 0 while the person is still clocked in. The UI represents that as Midnight. Because the record is active, you cannot edit it in Time and Expense entry (everything should be editable in that screen) and the Pay Hours is set to zero.
What options are available then to âfixâ this?
For this specific record, I know I can just do the User Run Conversion 660. But, this happens on a regular basis and I would prefer that the department heads fix the employee records for their team rather than having to jump into the conversion workbench every day.
And yes, I know having employees clock in/out properly is the only real fix, but we all know that the chances of getting that to happen is slim to none. There will always be mistakes.
All of our supervisors have a shortcut to Epicor MES on their desktop so they can clock in as that employee and clock them out. We donât have any password protection set up for employees on the floor.
You may be able to add the Active Trans checkbox to the T&E screen through customization. I donât know if that will be editable, though.
I know there have been some threads on here about clocking users out after a certain amount of time and some new functionality for clocking employees out in one of the next versions of Kinetic.
Only use ActiveTrans for finding clocked in workers. That is what the system uses to determine whether or not the labor is still clocked into. Whatever the clockout time says doesnât really matter. â0.00â (and for some reason, in my system, the occasional â24.00â that Epicor says shouldnât happen but still does) are basically undefined values while the transaction is ongoing.
Running the End Labor conversion will change the ActiveTrans flag to false. It doesnât appear to change anything else, so one should still adjust the time and mark the entry (for details) as approved.
Off the top of my head, either running COSWIP or a payroll for the period can lock the labor record. I donât recall which one does this. Itâs rare these days for me to get involved with this issue.
Iâve got few hard rules when it comes to this career, but âno user should ever log in as someone elseâ is one of them.
In a previous life I put a customization on the MES screen to clock users out of LaborDtl records. It utilized the LaborAdapter BO and ran the .EndActivity() method, closing out the LaborDtl records that were linked to the current LaborHed record.
Is there a similar method in the LaborAdapter for clocking out/ending the LaborHed record? I have looked throughthe LaborAdapter in the Custom Object Explorer but am not seeing anything that looks like the right one.
Or is it simply a matter of setting values for the ClockOutDate and ClockOutTime fields?
Personally, Iâd create a function that takes a LaborHedSeq as input, looks up all associated LaborDtlâs and bring that into a loop that calls Labor.EndActivity to close out each one.
Iâd then call that function from a pre-process BPM on whatever method the system calls when you clock out for the day. I donât recall if 10.2.400 has functions, but if it doesnât, then you can do basically the same thing entirely within the BPM. Because youâre doing this âpre-processâ (before the canned method fires) the whole loop should complete before the system does its checks for open labor details.
If you managed to do that from a screen customization ( ) then it should be easy for you to manage from BPM.
They (Epicor/Kinetic future release) will* allow a supervisor to clock in and make the transaction on behalf of them⌠not sure what type of logging they put in place to expose that the supervisor made the transaction as opposed to the employee themselves, but, itâs a start.
Our supervisors log into MES using their username and password and just use the employeeâs ID to clock in/out, so all of the standard change logs are still capturing that it was the supervisor who made the change instead of the employee out on the floor. I imagine change logs will still be the way to track who the actual user was that did the edit.
100% with you on that one. I know there are people in my shops that have shared their passwords with their managers and such, and when I hear that I force a password change on them. But, that is a different story. I am not trying to go that route.
I think you are right. I came across that just a few minutes ago myself. I am going to have to loop through the LaborDtl entries first, as suggested by @jtownsend, to do an EndActivity on them. I should probably put a reminder in place stating that they should probably go in and fix the Labor Quantities on those job(s) as well, eh? (that is just me thinking out loud)