private void recalculateRecord( final String recordId ) throws JANException
{
try
{
int recordsDaily = 2;
// 初始化RecordVO
final RecordVO recordVO = ( ( RecordDao ) getDao() ).getRecordVOByRecordId( recordId );
//获取系统设置的总的打卡次数
if ( recordVO != null )
{
if ( JANUtil.filterEmpty( recordVO.getContractId() ) != null )
{
final EmployeeContractVO employeeContractVO = this.getEmployeeContractDao().getEmployeeContractVOByContractId( recordVO.getContractId() );
if ( employeeContractVO != null && JANUtil.filterEmpty( employeeContractVO.getOrderId() ) != null )
{
final ClientOrderHeaderVO clientOrderHeaderVO = this.getClientOrderHeaderDao().getClientOrderHeaderVOByOrderHeaderId( employeeContractVO.getOrderId() );
if ( clientOrderHeaderVO != null && JANUtil.filterEmpty( clientOrderHeaderVO.getRecordsDaily() ) != null
&& Integer.valueOf( clientOrderHeaderVO.getRecordsDaily() ) > recordsDaily )
{
recordsDaily = Integer.valueOf( clientOrderHeaderVO.getRecordsDaily() );
}
}
}
//总打卡次数必须大于两次
if ( recordsDaily > 2 )
{
final RecordVO searchRecordVO = new RecordVO();
searchRecordVO.setContractId( recordVO.getContractId() );
searchRecordVO.setSignDate( recordVO.getSignDate() );
//获取这个员工当天打卡的所有记录
final List< Object > recordVOs = ( ( RecordDao ) getDao() ).getRecordVOsBySignDate( searchRecordVO );
if ( recordVOs != null && recordVOs.size() > 0 )
{
for ( Object targetRecordVOObject : recordVOs )
{
// 初始化目标记录
final RecordVO targetRecordVO = ( RecordVO ) targetRecordVOObject;
// 清除废弃表示
targetRecordVO.setAbandon( "2" );
// 初始化缓存记录 这里的值永远是每次循环里头时间最小的一次
RecordVO lastRecordVO = null;
long gapSeconds = 0;
int validRecords = 0;
//按打卡时间的升序取出集合,将集合中所有记录自比较,取非同一条记录下打卡时间小的并且没有废弃的记录,计算出最近打卡和最远打卡的时间差。
for ( Object recordVOObject : recordVOs )
{ //临时对象,用于暂时接收数据
final RecordVO tempRecordVO = ( RecordVO ) recordVOObject;
//由于集合本身是排好序的,因此循环结束取出的值是时间最小的值
if ( !tempRecordVO.getRecordId().equals( targetRecordVO.getRecordId() )
&& JANUtil.getSeconds( tempRecordVO.getSignDate() + " " + tempRecordVO.getSignTime() ) <= JANUtil.getSeconds( targetRecordVO.getSignDate() + " "
+ targetRecordVO.getSignTime() ) && ( JANUtil.filterEmpty( tempRecordVO.getAbandon() ) == null || tempRecordVO.getAbandon().equals( "2" ) ) )
{
lastRecordVO = tempRecordVO;
//当前打卡时间-最小打卡时间就是时间差
gapSeconds = JANUtil.getSeconds( targetRecordVO.getSignDate() + " " + targetRecordVO.getSignTime() )
- JANUtil.getSeconds( tempRecordVO.getSignDate() + " " + tempRecordVO.getSignTime() );
validRecords++;
}
}
if ( lastRecordVO != null )
{
final String recordBackupMinute = JANConstants.getJANAccountConstants( targetRecordVO.getAccountId() ).OPTIONS_RECORD_BACKUP_MINUTE;
if ( JANUtil.filterEmpty( recordBackupMinute ) != null && Double.valueOf( recordBackupMinute ) > 0
&& gapSeconds <= Double.valueOf( recordBackupMinute ) * 60 )
{//这是系统设定的有效打卡时间差,讲员工打卡最大时间差比较,在系统时间差范围内记录下这条打卡信息。 如果当前这次记录是签入但是时间不是最小的,则将当前这次作废。
//如果当前这次记录不是签入同时时间不是最小的,那么将小的这次作废,留下当前记录时间。 也就是签入的时候留下最小的时间,签出的时候留下最大时间。
targetRecordVO.setInOrOut( lastRecordVO.getInOrOut() );
if ( JANUtil.filterEmpty( lastRecordVO.getInOrOut() ) == null || lastRecordVO.getInOrOut().equals( "1" ) )
{
// 作废
targetRecordVO.setAbandon( "1" );
}
else
{
// 作废
lastRecordVO.setAbandon( "1" );
}
}
else
{ //两次打卡时间超出了系统设置补打卡有效时间之内的情况。 存在比当前记录还小的时间数,那么如果最小时间是签入,且和本次时间超出补卡范围,那么当前时间自然是迁出。
if ( validRecords < recordsDaily )
{
if ( lastRecordVO.getInOrOut().equals( "1" ) )
{
// 签出
targetRecordVO.setInOrOut( "2" );
}
else
{
// 签入
targetRecordVO.setInOrOut( "1" );
}
}
else
{//两次打卡时间超出了系统设置补打卡有效时间之内的情况。 没有比当前记录时间还小的情况,那么当前记录时间肯定是签出时间。当前最小时间肯定作废
// 签出
targetRecordVO.setInOrOut( "2" );
// 作废
lastRecordVO.setAbandon( "1" );
}
}
// 缓存记录修改
( ( RecordDao ) getDao() ).updateRecord( lastRecordVO );
}
else
{
// 签入---因为lastRecordVO时间最小的对象不存在,因此targetRecordVO本身就是最小的,就是说我们默认第一次打卡就是签入,不上迁出。不管第一次在早上或者下午
targetRecordVO.setInOrOut( "1" );
}
// 目标记录修改
( ( RecordDao ) getDao() ).updateRecord( targetRecordVO );
}
}
}
}
}
catch ( final Exception e )
{
throw new JANException( e );
}
}