/** * * @param Model_Tudu_Tudu $tudu * @param Model_App_Attend_Tudu_Apply $data */ public function updateCheckinApply(Model_Tudu_Tudu $tudu, Model_App_Attend_Tudu_Apply $data) { $data = $data->getAttributes(); /* @var $daoApply Dao_App_Attend_Apply */ $daoApply = Tudu_Dao_Manager::getDao('Dao_App_Attend_Apply', Tudu_Dao_Manager::DB_APP); /* @var $daoDate Dao_App_Attend_Date */ $daoDate = Tudu_Dao_Manager::getDao('Dao_App_Attend_Date', Tudu_Dao_Manager::DB_APP); /* @var $daoMonth Dao_App_Attend_Month */ $daoMonth = Tudu_Dao_Manager::getDao('Dao_App_Attend_Month', Tudu_Dao_Manager::DB_APP); /* @var $daoTotal Dao_App_Attend_Total */ $daoTotal = Tudu_Dao_Manager::getDao('Dao_App_Attend_Total', Tudu_Dao_Manager::DB_APP); /* @var $daoCheckin Dao_App_Attend_Checkin */ $daoCheckin = Tudu_Dao_Manager::getDao('Dao_App_Attend_Checkin', Tudu_Dao_Manager::DB_APP); // 更新相关状态 $daoApply->updateApply($data['applyid'], array('status' => 2)); $daoApply->updateReviewer($data['applyid'], $tudu->uniqueId, array('status' => 1)); // 签到 if ($data['checkintype'] == 0) { $type = 0; $checkinTime = $data['starttime']; // 签退 } elseif ($data['checkintype'] == 1) { $type = 1; $checkinTime = $data['endtime']; } $status = Dao_App_Attend_Checkin::STATUS_NORMAL; // 读取补签那天排班计划 $applyDate = strtotime(date('Y-m-d', $checkinTime)); $applyMonth = date('Ym', $applyDate); $plan = $this->getPlan($data['orgid'], $data['uniqueid'], $applyDate); if (!empty($plan) && $plan['scheduleid'] != '^off' && $plan['scheduleid'] != '^exemption') { // 上班签到 if ($type == Dao_App_Attend_Checkin::TYPE_CHECKIN && $plan['checkintime']) { $setCheckinTime = $applyDate + $this->formatTimeToSec($plan['checkintime']); if (!empty($plan['latestandard'])) { $setCheckinTime += $plan['latestandard'] * 60; } if ($checkinTime > $setCheckinTime) { $status = Dao_App_Attend_Checkin::STATUS_LATE; if (!empty($plan['latecheckin'])) { $outworkTime = $plan['latecheckin'] * 60; $setCheckinTime = $applyDate + $this->formatTimeToSec($plan['checkintime']); if ($checkinTime - $setCheckinTime > $outworkTime) { $status = Dao_App_Attend_Checkin::STATUS_WORK; } } } // 下班签退 } elseif ($type == Dao_App_Attend_Checkin::TYPE_CHECKOUT && $plan['checkouttime']) { $setCheckoutTime = $applyDate + $this->formatTimeToSec($plan['checkouttime']); $calType = 0; $cinTime = 0; if ($plan['checkintime']) { // 读取签到记录 $checkin = $daoCheckin->getCheckin(array('orgid' => $data['orgid'], 'uniqueid' => $data['uniqueid'], 'date' => $applyDate, 'type' => 0)); $calType = null === $checkin ? 0 : 1; if (null !== $checkin) { $cinTime = $this->formatTimeToSec(date('H:i', $checkin->createTime)); $planCinTime = $this->formatTimeToSec($plan['checkintime']); if ($planCinTime > $cinTime) { $cinTime = $planCinTime; } } } if ($cinTime == 0) { $calType = 0; } switch ($calType) { case 0: if ($checkinTime < $setCheckoutTime) { $status = Dao_App_Attend_Checkin::STATUS_LEAVE; if (!empty($plan['leavecheckout'])) { $outworkTime = $plan['leavecheckout'] * 60; $setCheckoutTime = $applyDate + $this->formatTimeToSec($plan['checkouttime']); if ($setCheckoutTime - $checkinTime > $outworkTime) { $status = Dao_App_Attend_Checkin::STATUS_WORK; } } } break; case 1: $planWorkTime = $this->formatTimeToSec($plan['checkouttime']) - $this->formatTimeToSec($plan['checkintime']); $userWorkTime = $this->formatTimeToSec(date('H:i', $checkinTime)) - $cinTime; if ($userWorkTime < $planWorkTime) { $status = Dao_App_Attend_Checkin::STATUS_LEAVE; if (!empty($plan['leavecheckout']) && $this->calculateTime($userWorkTime, $planWorkTime) > $plan['leavecheckout'] * 60) { $status = Dao_App_Attend_Checkin::STATUS_WORK; } } break; } } } $checkin = $daoCheckin->getCheckin(array('orgid' => $data['orgid'], 'uniqueid' => $data['uniqueid'], 'date' => $applyDate, 'type' => $type)); if (null === $checkin) { // 创建签到记录 $checkinId = $daoCheckin->createCheckin(array('checkinid' => Dao_App_Attend_Checkin::getCheckinId(), 'orgid' => $data['orgid'], 'uniqueid' => $data['uniqueid'], 'date' => $applyDate, 'status' => $status, 'type' => $type, 'createtime' => $checkinTime)); } else { if ($type == Dao_App_Attend_Checkin::TYPE_CHECKIN) { if ($checkin->createTime > $checkinTime) { $checkinId = $daoCheckin->updateCheckin($checkin->checkinId, array('status' => $status, 'createtime' => $checkinTime)); } else { $checkinId = $checkin->checkinId; } } elseif ($type == Dao_App_Attend_Checkin::TYPE_CHECKOUT) { if ($checkin->createTime < $checkinTime) { $checkinId = $daoCheckin->updateCheckin($checkin->checkinId, array('status' => $status, 'createtime' => $checkinTime)); } else { $checkinId = $checkin->checkinId; } } } if ($checkinId) { // 获取签到、签退状态 $checkinStatus = 0; if (!empty($plan) && $plan['scheduleid'] != '^off' && $plan['scheduleid'] != '^exemption') { $checkinStatus = $this->getCheckinStatus($plan, $data['uniqueid'], $applyDate); } $attendDate = $daoDate->getAttendDate(array('uniqueid' => $data['uniqueid'], 'date' => $applyDate)); if (!$attendDate) { $iswork = 1; if ($plan !== null && !$plan['checkintime'] && !$plan['checkouttime'] || empty($plan) || !empty($plan) && ($plan['scheduleid'] == '^off' || $plan['scheduleid'] == '^exemption') || $type == 0 && $plan !== null && !$plan['checkouttime'] && $status != Dao_App_Attend_Checkin::STATUS_WORK) { $iswork = 0; } $daoDate->create(array('orgid' => $data['orgid'], 'uniqueid' => $data['uniqueid'], 'date' => $applyDate, 'iswork' => $iswork, 'checkinstatus' => $checkinStatus, 'updatetime' => time())); } else { $sum = array($checkinStatus); if (!empty($attendDate->checkinStatus)) { foreach ($attendDate->checkinStatus as $item) { if ($item == 2) { $sum[] = 4; break; } } } $checkinStatus = array_sum($sum); $update = array('checkinstatus' => $checkinStatus); $rs = Dao_App_Attend_Date::formatCheckinStatus($checkinStatus); if (!empty($rs)) { foreach ($rs as $item) { if (0 == $item || 1 == $item) { $update['iswork'] = 1; break; } } } $daoDate->update($data['uniqueid'], $applyDate, $update); } // 判断月统计表是否已有当月的统计记录 $exists = $daoMonth->existsRecord($data['uniqueid'], $applyMonth); if (!$exists) { $daoMonth->create(array('orgid' => $data['orgid'], 'uniqueid' => $data['uniqueid'], 'date' => $applyMonth, 'updatetime' => time())); } } $this->attendCount($plan, $data['uniqueid'], $applyDate); $memo = array($data['categoryname'], $type, 0 == $type ? $data['starttime'] : $data['endtime']); $daoDate->addApply(array('orgid' => $data['orgid'], 'uniqueid' => $data['uniqueid'], 'date' => $applyDate, 'categoryid' => $data['categoryid'], 'memo' => implode('|', $memo))); // 统计考勤类型次数等 if (!$daoTotal->existsRecord($data['categoryid'], $data['uniqueid'], $applyMonth)) { $daoTotal->create(array('orgid' => $data['orgid'], 'uniqueid' => $data['uniqueid'], 'categoryid' => $data['categoryid'], 'date' => $applyMonth, 'total' => 1, 'updatetime' => time())); } else { $daoTotal->updateTotal($data['categoryid'], $data['uniqueid'], $applyMonth); } /* @var $daoTudu Dao_Td_Tudu_Tudu */ $daoTudu = Tudu_Dao_Manager::getDao('Dao_Td_Tudu_Tudu', Tudu_Dao_Manager::DB_TS); // 更新图度 $ret = $daoTudu->updateTudu($tudu->tuduId, array('isdone' => 1)); if (!$ret) { return false; } // 获取图度关联用户 $users = $daoTudu->getUsers($tudu->tuduId); // 标签操作 foreach ($users as $u) { $daoTudu->deleteLabel($tudu->tuduId, $u['uniqueid'], '^i'); //移除图度箱标签 $daoTudu->addLabel($tudu->tuduId, $u['uniqueid'], '^o'); //添加已完成标签 $daoTudu->deleteLabel($tudu->tuduId, $u['uniqueid'], '^a'); //移除我执行标签 $daoTudu->deleteLabel($tudu->tuduId, $u['uniqueid'], '^e'); //移除我审批标签 } }
/** * * @param string $uniqueId * @param int $type * @param array $dates */ public function updateAdjustAttend($uniqueId, $type, $dates) { $today = strtotime(date('Y-m-d')); if (empty($uniqueId) || $dates['starttime'] > $today) { return; } $dateArr = array(); $start = $dates['starttime']; $orgId = $this->_user->orgId; while ($start <= $today) { if ($start > $dates['endtime']) { break; } $dateArr[] = $start; $start += 86400; } /* @var $daoDate Dao_App_Attend_Date */ $daoDate = Tudu_Dao_Manager::getDao('Dao_App_Attend_Date', Tudu_Dao_Manager::DB_APP); /* @var $daoMonth Dao_App_Attend_Month */ $daoMonth = Tudu_Dao_Manager::getDao('Dao_App_Attend_Month', Tudu_Dao_Manager::DB_APP); $startDate = $dateArr[0]; $popDate = array_pop($dateArr); $endDate = $popDate + 86400; $condition = array('uniqueid' => $uniqueId, 'orgid' => $orgId, 'date' => array('start' => $startDate, 'end' => $endDate)); $attendDates = $daoDate->getAttendDates($condition)->toArray('date'); $arr = array(); $month = array(); foreach ($attendDates as $date => $item) { $arr[] = $date; $m = date('Ym', $date); if (!array_key_exists($m, $month)) { $month[$m] = array('month' => (int) date('m', $date), 'year' => (int) date('Y', $date)); } $params = array(); $sum = array(0); if (0 == $type) { if ($item['islate'] || $item['isleave'] || $item['iswork']) { $params['islate'] = 0; $params['isleave'] = 0; $params['iswork'] = 0; $params['checkinstatus'] = 0; } } else { $checkins = $this->getCheckins($uniqueId, $date); $plan = $this->getPlan($uniqueId, $date); $checkinStatus = !empty($plan) ? $this->getCheckinStatus($checkins, $plan) : 0; if (!empty($plan) && $plan['scheduleid'] != '^off' && $plan['scheduleid'] != '^exemption') { $isLate = false; $isLeave = false; $isWork = false; foreach ($checkins as $checkin) { if ($checkin['status'] == Dao_App_Attend_Checkin::STATUS_LATE) { $isLate = true; } elseif ($checkin['status'] == Dao_App_Attend_Checkin::STATUS_LEAVE) { $isLeave = true; } elseif ($checkin['status'] == Dao_App_Attend_Checkin::STATUS_WORK) { $isWork = true; } } if ($isWork) { $isLate = false; $isLeave = false; } $params['iswork'] = $isWork ? true : false; $params['islate'] = $isLate ? true : false; $params['isleave'] = $isLeave ? true : false; } $sum = array($checkinStatus); } if (!empty($item['checkinstatus'])) { foreach ($item['checkinstatus'] as $item) { if ($item == 2) { $sum[] = 4; break; } } } $checkinStatus = array_sum($sum); $params['checkinstatus'] = $checkinStatus; if (1 == $type && empty($params['iswork'])) { $rs = Dao_App_Attend_Date::formatCheckinStatus($checkinStatus); if (!empty($rs)) { foreach ($rs as $item) { if (0 == $item || 1 == $item) { $params['iswork'] = 1; break; } } } } if (!empty($params)) { $daoDate->update($uniqueId, $date, $params); } } if ($type == 1) { $diffDate = array_diff($dateArr, $arr); foreach ($diffDate as $d) { $m = date('Ym', $d); if (!array_key_exists($m, $month)) { $month[$m] = array('month' => (int) date('m', $d), 'year' => (int) date('Y', $d)); } $params = array('orgid' => $orgId, 'uniqueid' => $uniqueId, 'date' => $d, 'iswork' => 1); $daoDate->create($params); } } // 更新月统计 foreach ($month as $ym => $item) { $monthParams = array(); $sum = $daoDate->dateSum(array('uniqueid' => $uniqueId, 'startdate' => mktime(0, 0, 0, $item['month'], 1, $item['year']), 'enddate' => mktime(0, 0, 0, $item['month'] + 1, 1, $item['year']))); if (!empty($sum)) { $monthParams['updatetime'] = time(); $monthParams['late'] = (int) $sum['late']; $monthParams['leave'] = (int) $sum['leave']; $monthParams['unwork'] = (int) $sum['unwork']; $daoMonth->update($uniqueId, $ym, $monthParams); } } }
/** * Construct * * @param array $record */ public function __construct(array $record) { $this->orgId = $record['orgid']; $this->uniqueId = $record['uniqueid']; $this->trueName = isset($record['truename']) ? $record['truename'] : null; $this->deptName = isset($record['deptname']) ? $record['deptname'] : null; $this->date = $this->_toTimestamp($record['date']); $this->isLate = $this->_toBoolean($record['islate']); $this->isLeave = $this->_toBoolean($record['isleave']); $this->isWork = $this->_toBoolean($record['iswork']); $this->isAbnormalIp = isset($record['isabnormalip']) ? $this->_toBoolean($record['isabnormalip']) : null; $this->checkinStatus = Dao_App_Attend_Date::formatCheckinStatus($this->_toInt($record['checkinstatus'])); $this->workTime = $this->_toInt($record['worktime']); $this->memo = isset($record['memo']) ? Dao_App_Attend_Date::formatMemo($record['memo']) : null; $this->updateTime = $this->_toTimestamp($record['updatetime']); $this->categories = !empty($record['categories']) ? explode(',', $record['categories']) : array(); parent::__construct(); }
/** * 签到 */ public function checkinAction() { // 签到类型 $type = (int) $this->_request->getPost('type'); if (!isset($type)) { return $this->_this->json(false, $this->lang['error_type_of_checkin']); } // 签到时间 $checkinTime = time(); /* @var $daoIp Dao_Md_Ip_Info */ $daoIp = Tudu_Dao_Manager::getDao('Dao_Md_Ip_Info', Tudu_Dao_Manager::DB_MD); // 签到来源IP、ip位置 $clientIp = $this->_request->getClientIp(); $ipInfo = $daoIp->getInfoByIp($clientIp); /* @var $daoCheckin Dao_App_Attend_Checkin */ $daoCheckin = Tudu_Dao_Manager::getDao('Dao_App_Attend_Checkin', Tudu_Dao_Manager::DB_APP); // 默认当次签到类型为正常 $status = Dao_App_Attend_Checkin::STATUS_NORMAL; // 读取当前天排班信息 $plan = $this->getPlan(); if (!empty($plan) && $plan['scheduleid'] != '^off' && $plan['scheduleid'] != '^exemption') { // 上班签到 if ($type == Dao_App_Attend_Checkin::TYPE_CHECKIN && $plan['checkintime']) { $setCheckinTime = $this->_currentDate + $this->formatTimeToSec($plan['checkintime']); if (!empty($plan['latestandard'])) { $setCheckinTime += $plan['latestandard'] * 60; } if ($checkinTime > $setCheckinTime) { $status = Dao_App_Attend_Checkin::STATUS_LATE; if (!empty($plan['latecheckin'])) { $outworkTime = $plan['latecheckin'] * 60; $setCheckinTime = $this->_currentDate + $this->formatTimeToSec($plan['checkintime']); if ($checkinTime - $setCheckinTime > $outworkTime) { $status = Dao_App_Attend_Checkin::STATUS_WORK; } } } // 下班签退 } elseif ($type == Dao_App_Attend_Checkin::TYPE_CHECKOUT && $plan['checkouttime']) { $setCheckoutTime = $this->_currentDate + $this->formatTimeToSec($plan['checkouttime']); $calType = 0; $cinTime = 0; if ($plan['checkintime']) { // 读取签到记录 $checkin = $daoCheckin->getCheckin(array('orgid' => $this->_user->orgId, 'uniqueid' => $this->_user->uniqueId, 'date' => $this->_currentDate, 'type' => 0)); $calType = null === $checkin ? 0 : 1; if (null !== $checkin) { $cinTime = $this->formatTimeToSec(date('H:i', $checkin->createTime)); $planCinTime = $this->formatTimeToSec($plan['checkintime']); if ($planCinTime > $cinTime) { $cinTime = $planCinTime; } } } if ($cinTime == 0) { $calType = 0; } switch ($calType) { case 0: if ($checkinTime < $setCheckoutTime) { $status = Dao_App_Attend_Checkin::STATUS_LEAVE; if (!empty($plan['leavecheckout'])) { $outworkTime = $plan['leavecheckout'] * 60; $setCheckoutTime = $this->_currentDate + $this->formatTimeToSec($plan['checkouttime']); if ($setCheckoutTime - $checkinTime > $outworkTime) { $status = Dao_App_Attend_Checkin::STATUS_WORK; } } } break; case 1: $planWorkTime = $this->formatTimeToSec($plan['checkouttime']) - $this->formatTimeToSec($plan['checkintime']); $userWorkTime = $this->formatTimeToSec(date('H:i', $checkinTime)) - $cinTime; if ($userWorkTime < $planWorkTime) { $status = Dao_App_Attend_Checkin::STATUS_LEAVE; if (!empty($plan['leavecheckout']) && $this->calculateTime($userWorkTime, $planWorkTime) > $plan['leavecheckout'] * 60) { $status = Dao_App_Attend_Checkin::STATUS_WORK; } } break; } } } /* @var $daoDate Dao_App_Attend_Date */ $daoDate = Tudu_Dao_Manager::getDao('Dao_App_Attend_Date', Tudu_Dao_Manager::DB_APP); $checkin = $daoCheckin->getCheckin(array('orgid' => $this->_user->orgId, 'uniqueid' => $this->_user->uniqueId, 'date' => $this->_currentDate, 'type' => $type)); if (null === $checkin) { // 创建签到记录 $checkinId = $daoCheckin->createCheckin(array('checkinid' => Dao_App_Attend_Checkin::getCheckinId(), 'orgid' => $this->_user->orgId, 'uniqueid' => $this->_user->uniqueId, 'date' => $this->_currentDate, 'status' => $status, 'type' => $type, 'ip' => sprintf('%u', ip2long($clientIp)), 'address' => null !== $ipInfo ? $ipInfo->city : null, 'createtime' => $checkinTime)); } else { if ($type == Dao_App_Attend_Checkin::TYPE_CHECKIN) { if ($checkin->createTime > $checkinTime) { $checkinId = $daoCheckin->updateCheckin($checkin->checkinId, array('status' => $status, 'ip' => sprintf('%u', ip2long($clientIp)), 'address' => null !== $ipInfo ? $ipInfo->city : null, 'createtime' => $checkinTime)); } else { $checkinId = $checkin->checkinId; } } elseif ($type == Dao_App_Attend_Checkin::TYPE_CHECKOUT) { if ($checkin->createTime < $checkinTime) { $checkinId = $daoCheckin->updateCheckin($checkin->checkinId, array('status' => $status, 'ip' => sprintf('%u', ip2long($clientIp)), 'address' => null !== $ipInfo ? $ipInfo->city : null, 'createtime' => $checkinTime)); } else { $checkinId = $checkin->checkinId; } } } // 创建当天考勤统计,默认旷工 if ($checkinId) { // 获取签到、签退状态 $checkinStatus = 0; if (!empty($plan) && $plan['scheduleid'] != '^off' && $plan['scheduleid'] != '^exemption') { $checkinStatus = $this->getCheckinStatus($plan); } $attendDate = $daoDate->getAttendDate(array('uniqueid' => $this->_user->uniqueId, 'date' => $this->_currentDate)); if (!$attendDate) { $iswork = 1; if ($plan !== null && !$plan['checkintime'] && !$plan['checkouttime'] || empty($plan) || !empty($plan) && ($plan['scheduleid'] == '^off' || $plan['scheduleid'] == '^exemption') || $type == 0 && $plan !== null && !$plan['checkouttime'] && $status != Dao_App_Attend_Checkin::STATUS_WORK) { $iswork = 0; } $daoDate->create(array('orgid' => $this->_user->orgId, 'uniqueid' => $this->_user->uniqueId, 'date' => $this->_currentDate, 'iswork' => $iswork, 'checkinstatus' => $checkinStatus, 'updatetime' => time())); } else { $sum = array($checkinStatus); if (!empty($attendDate->checkinStatus)) { foreach ($attendDate->checkinStatus as $item) { if ($item == 2) { $sum[] = 4; break; } } } $checkinStatus = array_sum($sum); $update = array('checkinstatus' => $checkinStatus); $rs = Dao_App_Attend_Date::formatCheckinStatus($checkinStatus); if (!empty($rs)) { foreach ($rs as $item) { if (0 == $item || 1 == $item) { $update['iswork'] = 1; break; } } } $daoDate->update($this->_user->uniqueId, $this->_currentDate, $update); } // 判断月统计表是否已有当月的统计记录 /* @var $daoMonth Dao_App_Attend_Month */ $daoMonth = Tudu_Dao_Manager::getDao('Dao_App_Attend_Month', Tudu_Dao_Manager::DB_APP); $exists = $daoMonth->existsRecord($this->_user->uniqueId, $this->_currentMonth); if (!$exists) { $daoMonth->create(array('orgid' => $this->_user->orgId, 'uniqueid' => $this->_user->uniqueId, 'date' => $this->_currentMonth, 'updatetime' => time())); } } else { return $this->_this->json(false, $this->lang['checkin_failed']); } // 下班签退,进行当天考勤统计(工作时长等)、当月考勤统计 if ($type == Dao_App_Attend_Checkin::TYPE_CHECKOUT) { $this->attendCount($plan); } $message = $type == Dao_App_Attend_Checkin::TYPE_CHECKOUT ? '签退成功' : '签到成功'; return $this->_this->json(true, $message, array('status' => $status, 'ip' => $clientIp, 'address' => !empty($ipInfo->city) ? $ipInfo->city : $this->lang['unknow'], 'time' => date('H:i', $checkinTime))); }