kaoqinModel.php 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243
  1. <?php
  2. /**
  3. * 考勤的model
  4. */
  5. class kaoqinClassModel extends Model
  6. {
  7. private $userarr = array();
  8. private $_pipeiarr = array();
  9. public $admindb,$sjoindb,$dtobj,$_dkarr,$tempsbstatus;
  10. public function initModel()
  11. {
  12. $this->settable('kqdist');
  13. $this->admindb = m('admin');
  14. $this->sjoindb = m('sjoin');
  15. $this->dtobj = c('date');
  16. }
  17. public function adddkjl($uid,$type=0, $dkdt='',$ip='',$mac='')
  18. {
  19. $now = $this->rock->now;
  20. if($dkdt=='')$dkdt = $now;
  21. if($ip=='')$ip=$this->rock->ip;
  22. $xh = c('xinhu');
  23. $kqa = $this->admindb->getusinfo($uid,'dkip,dkmac');
  24. $mac = strtolower($mac);
  25. if(isempt($kqa['dkip']) && isempt($kqa['dkmac']))return '未设置打卡IP或MAC地址'.$xh->helpstr('kaoqin').'';
  26. if(!isempt($kqa['dkip']) && $kqa['dkip']!='*'){
  27. $ass = explode(',', $kqa['dkip']);
  28. if(!in_array($ip, $ass))return '打卡电脑IP必须是:'.$kqa['dkip'].',当前IP是:'.$ip.''.$xh->helpstr('kaoqin').'';
  29. }
  30. if(!isempt($kqa['dkmac'])){
  31. if($mac=='')return '无法获取MAC地址,请使用REIM客户端,'.$xh->helpstr('client','下载').'';
  32. $dkmac = str_replace('-',':',strtolower($kqa['dkmac']));
  33. $ass = explode(',', $dkmac);
  34. if(!in_array($mac, $ass))return '打卡电脑MAC地址必须是:'.$kqa['dkmac'].',当前MAC地址是:'.$mac.'';
  35. }
  36. $this->db->record('[Q]kqdkjl',array(
  37. 'dkdt' => $dkdt,
  38. 'uid' => $uid,
  39. 'optdt' => $now,
  40. 'ip' => $ip,
  41. 'mac' => $mac,
  42. 'comid' => $this->admindb->getcompanyid($uid),
  43. 'type' => $type
  44. ));
  45. $dt = substr($dkdt, 0, 10);
  46. $this->kqanay($uid, $dt);
  47. return '';
  48. }
  49. /**
  50. * 读取考勤时间
  51. * $lx0 考勤时段,$lx1上班时间
  52. */
  53. public function getkqsj($uid, $dt, $lx=0)
  54. {
  55. $key = $this->rock->getfunkey(func_get_args(),'kqdist');
  56. $rows = arrvalue($this->_pipeiarr, $key);
  57. if($rows)return $rows;
  58. $mid = $this->getdistid($uid, $dt, 0);
  59. $rows = $this->getkqsjs($mid);
  60. if($lx==1){
  61. $this->_pipeiarr[$key] = $rows;
  62. return $rows;
  63. }
  64. foreach($rows as $k=>$rs){
  65. $rows[$k]['children'] = $this->getkqsjs($rs['id']);
  66. }
  67. $this->_pipeiarr[$key] = $rows;
  68. return $rows;
  69. }
  70. private $getkqsjsarr = array();
  71. private function getkqsjs($id)
  72. {
  73. if(!isset($this->getkqsjsarr[$id])){
  74. $rows = $this->db->getrows('[Q]kqsjgz','pid='.$id.'','id,name,stime,etime,qtype,sort,iskt,iskq,isxx','`sort`');
  75. $this->getkqsjsarr[$id] = $rows;
  76. }
  77. return $this->getkqsjsarr[$id];
  78. }
  79. /**
  80. * 读取某人一天考勤类型状态
  81. */
  82. public function getkqztarr($uid, $dt)
  83. {
  84. $kqzt = $this->getkqsj($uid, $dt);
  85. $kqsr = array(); $xu = 0;
  86. foreach($kqzt as $k=>$rs){
  87. foreach($rs['children'] as $rs1){
  88. if(!isset($kqsr[$rs1['name']])){
  89. $kqsr[$rs1['name']]='state'.$xu.'';
  90. $xu++;
  91. }
  92. }
  93. }
  94. return $kqsr;
  95. }
  96. /**
  97. * 获取匹配Id
  98. * $type 0考勤时间,1休息,2定位
  99. */
  100. private $getdistrows = array();
  101. public function getdistid($uid, $dt, $type=0)
  102. {
  103. //根据排班来
  104. if($type==0){
  105. $pbarr = $this->getpbarr($dt);
  106. if($pbarr){
  107. $key0 = 'a'.$dt.'_'.$uid.'_2_0';//休息key
  108. if(isset($pbarr[$key0]))return $pbarr[$key0];
  109. //根据组来判断考勤时间规则
  110. $gids = $this->sjoindb->getgroupid($uid); //组Id
  111. if($gids!='0'){
  112. $gidar = explode(',', $gids);
  113. for($i=1; $i<count($gidar); $i++){
  114. $gid = $gidar[$i];
  115. $key0 = 'a'.$dt.'_'.$gid.'_1_0';
  116. if(isset($pbarr[$key0]))return $pbarr[$key0];
  117. }
  118. }
  119. }
  120. }
  121. $uarr[] = 'u'.$uid.'';
  122. $urs = $this->getusarr($uid);
  123. $deptpath = arrvalue($urs, 'deptpath');
  124. if(!isempt($deptpath)){
  125. $depa = explode(',', str_replace(array('[',']'), array('',''), $deptpath));
  126. foreach($depa as $depas){
  127. $uarr[] = 'd'.$depas.'';
  128. }
  129. }
  130. $groupname = arrvalue($urs, 'groupname');
  131. if(!isempt($groupname)){
  132. $depa = explode(',', $groupname);
  133. foreach($depa as $depas){
  134. $uarr[] = 'g'.$depas.'';
  135. }
  136. }
  137. if(!isset($this->getdistrows[$type])){
  138. $barr = $this->getall("`status`=1 and `type`=".$type." ",'*', '`sort`');
  139. foreach($barr as $k=>$rs)if(isempt($rs['enddt']))$barr[$k]['enddt'] = $rs['startdt'];
  140. $this->getdistrows[$type] = $barr;
  141. }else{
  142. $barr = $this->getdistrows[$type];
  143. }
  144. $rows = array();
  145. if($barr)foreach($barr as $k=>$rs){
  146. $receid = $rs['receid'];
  147. if($dt<$rs['startdt'] || $dt>$rs['enddt'])continue;
  148. if(isempt($receid) || $receid=='all'){
  149. $rows[] = $rs;
  150. continue;
  151. }
  152. $receida = explode(',', $receid);
  153. $bo = false;
  154. foreach($uarr as $uarrs){
  155. if(in_array($uarrs, $receida))$bo=true;
  156. }
  157. if($bo)$rows[] = $rs;
  158. }
  159. $mid = $this->getpipeimid($uid, $rows);
  160. if($type==0){
  161. }
  162. return $mid;
  163. }
  164. //从排班表kqdisv读取记录
  165. private $getpbarrs = array();
  166. private function getpbarr($dt)
  167. {
  168. $month= substr($dt, 0, 7);
  169. if(!isset($this->getpbarrs[$month])){
  170. $gset = $this->db->getall("select * from `[Q]kqdisv` where `dt` like '".$month."%' order by `type`");
  171. $setar= array();
  172. foreach($gset as $k=>$rs){
  173. $key = 'a'.$rs['dt'].'_'.$rs['receid'].'_'.$rs['plx'].'_'.$rs['type'].'';
  174. $setar[$key] = $rs['mid'];
  175. }
  176. $this->getpbarrs[$month] = $setar;
  177. return $setar;
  178. }else{
  179. return $this->getpbarrs[$month];
  180. }
  181. }
  182. /**
  183. * 是不是工作日
  184. */
  185. private $isworkdtarr = array();
  186. public function isworkdt($uid, $dt)
  187. {
  188. //先从排班那读取
  189. $pbarr = $this->getpbarr($dt);
  190. if($pbarr){
  191. $key1 = 'a'.$dt.'_'.$uid.'_2_1';//休息key
  192. $key2 = 'a'.$dt.'_'.$uid.'_2_2';//工作日key
  193. if(isset($pbarr[$key2]))return 1;
  194. if(isset($pbarr[$key1]))return 0;
  195. //根据组来判断排班
  196. $gids = $this->sjoindb->getgroupid($uid); //组Id
  197. if($gids!='0'){
  198. $gidar = explode(',', $gids);
  199. for($i=1; $i<count($gidar); $i++){
  200. $gid = $gidar[$i];
  201. $key2 = 'a'.$dt.'_'.$gid.'_1_2';
  202. if(isset($pbarr[$key2]))return 1;
  203. }
  204. for($i=1; $i<count($gidar); $i++){
  205. $gid = $gidar[$i];
  206. $key1 = 'a'.$dt.'_'.$gid.'_1_1';
  207. if(isset($pbarr[$key1]))return 0;
  208. }
  209. }
  210. }
  211. $month = substr($dt, 0, 7);
  212. $key = 'a'.$month.'';
  213. $barr = array();
  214. if(!isset($this->isworkdtarr[$key])){
  215. $rows = $this->db->getrows('[Q]kqxxsj',"`dt` like '$month%'");
  216. foreach($rows as $k=>$rs){
  217. $barr['a'.$rs['pid'].''.$rs['dt'].'_'.$rs['uid'].''] = $rs['type'];
  218. }
  219. $this->isworkdtarr[$key] = $barr;
  220. }else{
  221. $barr = $this->isworkdtarr[$key];
  222. }
  223. $isw = 1;
  224. $mid = $this->getdistid($uid, $dt, 1);
  225. $type = arrvalue($barr, 'a'.$mid.''.$dt.'_0');
  226. if($type=='0')$isw = 0;
  227. $types = arrvalue($barr, 'a'.$mid.''.$dt.'_'.$uid.'');
  228. if(!isempt($types))$isw = (int)$types;
  229. //$tos = $this->db->rows('[Q]kqxxsj',"`pid`=$mid and `dt`='$dt'");
  230. //$isw = ( $tos>0 ) ? 0 : 1;
  231. return $isw;
  232. }
  233. //返回人员
  234. public function getusarr($uid)
  235. {
  236. if(is_array($uid)){
  237. return $uid;
  238. }else{
  239. if(!isset($this->userarr[$uid])){
  240. $_urs = $this->db->getone('[Q]admin', "`id`='$uid'", '`id`,`deptid`,`deptpath`,`groupname`');
  241. $this->userarr[$uid] = $_urs;
  242. return $_urs;
  243. }else{
  244. return $this->userarr[$uid];
  245. }
  246. }
  247. }
  248. /**
  249. * 读取人员定位定位打卡位置
  250. */
  251. public function dwdkrs($uid, $dt)
  252. {
  253. $mid = $this->getdistid($uid, $dt, 2);
  254. return m('kqdw')->getone($mid);
  255. }
  256. /**
  257. * 数组匹配人员对应哪个记录
  258. */
  259. public function getpipeimid($uid=0, $garrs=array(), $esfi='mid', $momid=1, $dt='')
  260. {
  261. $mid = $momid;
  262. if($uid==0)return $mid;
  263. $mid = 0;
  264. $uarr = $this->getusarr($uid);
  265. $deptpath = arrvalue($uarr, 'deptpath');
  266. $uid = arrvalue($uarr, 'id','0');
  267. $utid = $dtid = array();$allars=false;$dttime = 0;
  268. if($dt!='')$dttime = strtotime($dt);
  269. foreach($garrs as $k=>$rs){
  270. $artid = explode(',', (string)$rs['receid']);
  271. if($dttime>0){
  272. if(!isset($rs['starttime'])){
  273. $rs['starttime'] = strtotime($rs['startdt']);
  274. $rs['endtime'] = strtotime($rs['enddt']);
  275. }
  276. if($rs['starttime'] > $dttime || $rs['endtime'] < $dttime)continue;
  277. }
  278. foreach($artid as $ssid){
  279. if($ssid=='')continue;
  280. if($ssid=='all'){
  281. $allars = $rs;
  282. continue;
  283. }
  284. $fs = substr($ssid, 0, 1);
  285. $sid = str_replace(array('u','d','g'), array('','',''), $ssid);
  286. if($fs=='g'){
  287. $guar = $this->admindb->getgrouptouid($sid);
  288. if($guar!=''){
  289. $guara = explode(',', $guar);
  290. foreach($guara as $guid){
  291. $utid[$guid][]= $rs;
  292. }
  293. }
  294. continue;
  295. }
  296. if($fs=='d'){
  297. $dtid[$sid][]= $rs;
  298. }else{
  299. $utid[$sid][]= $rs;
  300. }
  301. }
  302. }
  303. if(isset($utid[$uid]))$mid = (int)$utid[$uid][0][$esfi];
  304. if($mid == 0 && !$this->isempt($deptpath)){
  305. $depa = explode(',', str_replace(array('[',']'), array('',''), $deptpath));
  306. foreach($depa as $depas){
  307. if(isset($dtid[$depas]))$mid = (int)$dtid[$depas][0][$esfi];
  308. }
  309. }
  310. if($mid == 0 && is_array($allars))$mid = (int)$allars[$esfi];
  311. if($mid==0)$mid=$momid;
  312. return $mid;
  313. }
  314. //返回条件
  315. private $limitfenqxi = 20;//一次分析20人
  316. private $qingjiaarr = array();//读取对应人请假的数字[$uid][$month] = [{}];
  317. public function kqanayallfirst($month,$glx=0)
  318. {
  319. $month = substr($month, 0, 7);
  320. $start = ''.$month.'-01';
  321. $enddt = $this->dtobj->getenddt($month);
  322. $s = "and (`quitdt` is null or `quitdt`>='$start') and (`workdate` is null or `workdate`<='$enddt')";
  323. if($glx==0)return $s;
  324. $count = $this->admindb->rows('1=1 '.$s.'');
  325. $limit = $this->limitfenqxi;
  326. $maxpage= ceil($count/$limit);
  327. return array(
  328. 'count' => $count,
  329. 'limit' => $limit,
  330. 'maxpage' => $maxpage,
  331. );
  332. }
  333. public function kqanayall($month, $where='', $page=0)
  334. {
  335. if(isempt($month))return;
  336. $month = substr($month, 0, 7);
  337. $s = $this->kqanayallfirst($month).' '.$where.'';
  338. $max = $this->dtobj->getmaxdt($month);
  339. $sql = "select `id`,`workdate`,`quitdt` from `[Q]admin` where 1=1 ".$s."";
  340. $limit = $this->limitfenqxi;
  341. if($page>0){
  342. $sql.=" limit ".($page-1)*$limit.",".$limit."";
  343. }
  344. $urows = $this->db->getall($sql);
  345. $oi = 0;
  346. foreach($urows as $k=>$urs){
  347. $this->kqanaymonth($urs['id'], $month, $urs, $max);
  348. $oi++;
  349. }
  350. return $oi;
  351. }
  352. public function kqanayalldt($dt)
  353. {
  354. $s = "and (`quitdt` is null or `quitdt`>='$dt') and (`workdate` is null or `workdate`<='$dt')";
  355. $urows = $this->admindb->getall('1=1 '.$s.'', '`id`,`workdate`,`quitdt`');
  356. foreach($urows as $k=>$urs){
  357. $this->kqanay($urs['id'], $dt);
  358. }
  359. }
  360. public function kqanaymonth($uid, $month, $urs=false, $max=0)
  361. {
  362. $month = substr($month, 0, 7);
  363. if(!$urs)$urs = $this->admindb->getone($uid, '`workdate`,`quitdt`,`id`');
  364. if($max==0)$max = $this->dtobj->getmaxdt($month);
  365. $this->getqingjiaqj($uid, $month);
  366. for($i=1; $i<=$max; $i++){
  367. $oi = $i;if($oi<10)$oi='0'.$i.'';
  368. $dt = ''.$month.'-'.$oi.'';
  369. if(!isempt($urs['workdate']) && $urs['workdate']>$dt)continue;
  370. if(!isempt($urs['quitdt']) && $urs['quitdt']<$dt)continue;
  371. $this->kqanay($uid, $dt);
  372. }
  373. $this->delquitwork($urs, $month, $max);
  374. }
  375. //读取请假和外出记录
  376. private function getqingjiaqj($uid, $month)
  377. {
  378. $month = substr($month, 0, 7);
  379. $rows = $this->db->getall("select `stime`,`etime`,`qjkind` from `[Q]kqinfo` where `uid`='$uid' and `status`=1 and `isturn`=1 and `kind`='请假' and `stime` like '$month%' order by `stime`");
  380. $this->qingjiaarr[$uid][$month]['qingjia'] = $rows;
  381. $rows = $this->db->getall("select `outtime` as `stime`,`intime` as `etime`,`atype` from `[Q]kqout` where `uid`='$uid' and `status`=1 and `isturn`=1 and `outtime` like '$month%' order by `outtime`");
  382. $this->qingjiaarr[$uid][$month]['waichu'] = $rows;
  383. }
  384. //读取当天请假和外出的
  385. private function getqingjiaqjs($uid, $dt, $lx)
  386. {
  387. $dt = substr($dt, 0, 10);
  388. $month = substr($dt, 0, 7);
  389. if(!isset($this->qingjiaarr[$uid]) || !isset($this->qingjiaarr[$uid][$month])){
  390. $this->getqingjiaqj($uid, $dt);
  391. }
  392. $rows = $this->qingjiaarr[$uid][$month][$lx];
  393. $barr = array();
  394. if($rows)foreach($rows as $k=>$rs){
  395. $stime = substr($rs['stime'], 0, 10);
  396. $etime = substr($rs['etime'], 0, 10);
  397. if($dt>=$stime && $dt<=$etime)$barr[]=$rs;//在对应日期里
  398. }
  399. return $barr;
  400. }
  401. private function delquitwork($urs, $month, $max)
  402. {
  403. $ds = array();
  404. $dt1= ''.$month.'-01'; $dt2= ''.$month.'-'.$max.'';
  405. $uid= $urs['id'];
  406. if(!isempt($urs['workdate'])){
  407. if($urs['workdate']>$dt1)$ds[] = "dt<'".$urs['workdate']."'";
  408. }
  409. if(!isempt($urs['quitdt'])){
  410. if($urs['quitdt']<$dt2)$ds[] = "dt>'".$urs['quitdt']."'";
  411. }
  412. $str = join(' or ', $ds);
  413. if(!isempt($str))$this->db->delete('[Q]kqanay',"`uid`=$uid and ($str)");
  414. }
  415. private function geetdkarr($uid, $dt)
  416. {
  417. return $this->db->getrows('[Q]kqdkjl',"`uid`='$uid' and `dkdt` like '$dt%'",'`dkdt`','`dkdt` asc');
  418. }
  419. /**
  420. * 考勤分析
  421. * @param $uid 用户Id
  422. * @param $dt 分析日期
  423. */
  424. public function kqanay($uid, $dt)
  425. {
  426. if($dt > $this->rock->date)return;
  427. $dkarr = $this->geetdkarr($uid, $dt);
  428. $iswork = $this->isworkdt($uid, $dt);
  429. $sjarr = $this->getkqsj($uid, $dt);
  430. $db = m('kqanay');
  431. $ids = '0';
  432. //是否有跨天的
  433. $isjy_1 = $isjy_2 = 0;
  434. foreach($sjarr as $k=>$rs){
  435. foreach($rs['children'] as $k1=>$rs1){
  436. if($rs1['iskt']==2)$isjy_2=1; //-1天
  437. if($rs1['iskt']==1)$isjy_1=1; //+1天
  438. }
  439. }
  440. if($isjy_2==1){
  441. $dt2 = $this->dtobj->adddate($dt,'d', -1);
  442. $dtarr2 = $this->geetdkarr($uid, $dt2);
  443. if($dtarr2)$dkarr = array_merge($dtarr2, $dkarr);
  444. }
  445. if($isjy_1==1){
  446. $dt1 = $this->dtobj->adddate($dt,'d', 1);
  447. $dtarr1 = $this->geetdkarr($uid, $dt1);
  448. if($dtarr1)$dkarr = array_merge($dkarr, $dtarr1);
  449. }
  450. $this->_dkarr = $dkarr;
  451. $zshu = count($sjarr);
  452. $this->tempsbstatus = '';
  453. if($zshu==4)$this->tempsbstatus = $this->getstatessqj($sjarr[0], $dt, $uid); //[特殊判断]上午请假状态
  454. foreach($sjarr as $k=>$rs){
  455. if($rs['iskq']=='0')continue;//不用考勤就不分析了
  456. $ztname = $rs['name'];
  457. $arrs = $this->kqanaysss($uid, $dt, $rs, $this->_dkarr, $k, $zshu);
  458. $state = $arrs['state'];
  459. $states = $arrs['states'];
  460. $timesb = $timeys = 0;
  461. //判断是否有请假和外出。。
  462. if($iswork==1 && $state !='正常'){
  463. $zcarr = $arrs['zcarr'];
  464. if($zcarr && $states=='')$states = $this->getstates($zcarr, $dt, $uid);
  465. }
  466. $emiao = $arrs['emiao']; //迟到早退秒数
  467. $time = $arrs['time'];
  468. //是工作时间段
  469. if($rs['isxx']=='0'){
  470. $mshu = strtotime(''.$dt.' '.$rs['stime'].'') - strtotime(''.$dt.' '.$rs['etime'].'');
  471. $timesb = abs(round($mshu / 60 / 60,1));
  472. if($state=='正常' || !isempt($states)){
  473. $timeys = $timesb;
  474. }else{
  475. if($emiao>0){
  476. $timeys = round((abs($mshu) - $emiao)/60/60, 1);
  477. }
  478. }
  479. }
  480. $arr = array(
  481. 'ztname' => $ztname,
  482. 'state' => $state,
  483. 'states' => $states,
  484. 'remark' => $arrs['remark'],
  485. 'time' => $time,
  486. 'uid' => $uid,
  487. 'dt' => $dt,
  488. 'sort' => $k,
  489. 'iswork' => $iswork,
  490. 'optdt' => $this->rock->now,
  491. 'emiao' => $emiao,
  492. 'timesb' => $timesb,
  493. 'timeys' => $timeys
  494. );
  495. $where = "`uid`='$uid' and `dt`='$dt' and `ztname`='$ztname'";
  496. $id = (int)$db->getmou('id', $where);
  497. if($id==0)$where='';
  498. $db->record($arr, $where);
  499. if($id==0)$id = $this->db->insert_id();
  500. $ids.=','.$id.'';
  501. }
  502. $db->delete("id not in ($ids) and `uid`='$uid' and `dt`='$dt'");
  503. }
  504. private function kqanaysss($uid, $dt, $kqrs, $dkarr, $noi, $zshu)
  505. {
  506. $kqarr = $kqrs['children'];
  507. $state = '未打卡';$states = $remark = ''; $emiao = 0; $tpk=-1; $time = ''; $pdtime = 0;
  508. $zcarr = array();
  509. foreach($kqarr as $k2=>$cog2){
  510. if($cog2['name']=='正常')$zcarr = $cog2;//正常状态的
  511. }
  512. if($dkarr && $kqarr)foreach($kqarr as $k=>$rs){
  513. $stime = strtotime(''.$dt.' '.$rs['stime'].'');
  514. $etime = strtotime(''.$dt.' '.$rs['etime'].'');
  515. $qtype = $rs['qtype'];
  516. $iskt = $rs['iskt'];
  517. //-1跨天
  518. if($iskt==2){
  519. $dt2 = $this->dtobj->adddate($dt,'d', -1);
  520. $stime = strtotime(''.$dt2.' '.$rs['stime'].'');
  521. if($rs['stime']<$rs['etime']){
  522. $etime = strtotime(''.$dt2.' '.$rs['etime'].'');
  523. }
  524. }
  525. //+1跨天
  526. if($iskt==1){
  527. $dt1 = $this->dtobj->adddate($dt,'d', 1);
  528. $etime = strtotime(''.$dt1.' '.$rs['etime'].'');
  529. if($rs['stime']<$rs['etime']){
  530. $stime = strtotime(''.$dt1.' '.$rs['stime'].'');
  531. }
  532. }
  533. foreach($dkarr as $k1=>$rs1){
  534. $dkdt = strtotime($rs1['dkdt']);
  535. if($stime>$dkdt || $etime<$dkdt)continue;
  536. $time = $dkdt;
  537. $state = $rs['name'];
  538. $tpk = $k1;
  539. if($qtype==0)break;
  540. }
  541. $pdtime = $stime;
  542. if($qtype==1)$pdtime = $etime;
  543. if($time!='')break;
  544. }
  545. //4个状态,第2个状态需要额外处理,判断是不是请假的,上午全请假才需要判断
  546. $lxs = '';
  547. if($zshu==4 && $noi==1 && $zcarr){
  548. $lxs = $this->tempsbstatus;
  549. if($lxs!='')$states = $this->getstates($zcarr, $dt, $uid);
  550. }
  551. if($time!=''){
  552. if($state!='正常'){
  553. $emiao = $pdtime-$time;
  554. }
  555. if($lxs=='')unset($this->_dkarr[$tpk]);//一次打卡记录只能使用一次
  556. }
  557. $barr['state'] = $state;
  558. $barr['emiao'] = abs($emiao);
  559. if($time!='')$time = date('Y-m-d H:i:s', $time);
  560. $barr['time'] = $time;
  561. $barr['states'] = $states;
  562. $barr['remark'] = $remark;
  563. $barr['zcarr'] = $zcarr;
  564. if($pdtime!=0)$barr['pdtime'] = date('Y-m-d H:i:s', $pdtime);
  565. return $barr;
  566. }
  567. //【2019-05-12】判断是不是半天请假和外出了,只用于有每天4个考勤状态的
  568. private function getstatessqj($sbarr, $dts, $uid)
  569. {
  570. $rows = $this->getqingjiaqjs($uid, $dts,'qingjia');
  571. $st1 = strtotime($dts.' '.$sbarr['stime']);
  572. $et1 = strtotime($dts.' '.$sbarr['etime']);
  573. $lxs = '';
  574. foreach($rows as $k=>$rs){
  575. $qst = strtotime($rs['stime']);
  576. $qet = strtotime($rs['etime']);
  577. if($qst<=$st1 && $qet>=$et1){
  578. $lxs = $rs['qjkind'];
  579. }
  580. }
  581. if($lxs==''){
  582. $rows = $this->getqingjiaqjs($uid, $dts,'waichu');
  583. foreach($rows as $k=>$rs){
  584. $qst = strtotime($rs['stime']);
  585. $qet = strtotime($rs['etime']);
  586. if($qst<=$st1 && $qet>=$et1){
  587. $lxs = $rs['atype'];
  588. }
  589. }
  590. }
  591. return $lxs;
  592. }
  593. /**
  594. * 上班: (当前qtype==0)请假开始时间小于等于 设置正常的截止时间(取最小值)
  595. * 下班: (当前qtype==1)请假截止时间大于等于 设置正常的开始时间(取最大值)
  596. * 最新取消
  597. */
  598. private function getstates($ztarr, $dts, $uid)
  599. {
  600. $st1 = strtotime($dts.' '.$ztarr['stime']);
  601. $et1 = strtotime($dts.' '.$ztarr['etime']);
  602. $s = '';
  603. $rows = $this->getqingjiaqjs($uid, $dts,'qingjia');
  604. foreach($rows as $k=>$rs){
  605. $qst = strtotime($rs['stime']);
  606. $qet = strtotime($rs['etime']);
  607. if(($st1>=$qst && $st1<=$qet) || ($et1>=$qst && $et1<=$qet)){
  608. $s = $rs['qjkind'];
  609. break;
  610. }
  611. }
  612. if($s==''){
  613. $rows = $this->getqingjiaqjs($uid, $dts,'waichu');
  614. foreach($rows as $k=>$rs){
  615. $qst = strtotime($rs['stime']);
  616. $qet = strtotime($rs['etime']);
  617. if(($st1>=$qst && $st1<=$qet) || ($et1>=$qst && $et1<=$qet)){
  618. $s = $rs['atype'];
  619. break;
  620. }
  621. }
  622. }
  623. return $s;
  624. }
  625. /**
  626. * 获取默人对月份所有考勤状态{'2017-01-17':[{name:'上班','state':'正常'}]}
  627. */
  628. public function getanay($uid, $month, $dt='')
  629. {
  630. $month = substr($month, 0, 7);
  631. $dtobj = c('date');
  632. $max = $dtobj->getmaxdt($month);
  633. $startdt= ''.$month.'-01';
  634. $enddt = ''.$month.'-'.$max.'';
  635. if($dt!=''){
  636. $startdt = $dt;
  637. $enddt = $dt;
  638. }
  639. $rows = $this->db->getrows('[Q]kqanay',"`uid`='$uid' and `dt` between '$startdt' and '$enddt'",'*','dt,sort');
  640. $barr = array();
  641. foreach($rows as $k=>$rs){
  642. if(!isset($barr[$rs['dt']]))$barr[$rs['dt']]=array();
  643. $barr[$rs['dt']][] = $rs;
  644. }
  645. return $barr;
  646. }
  647. /**
  648. * 计算剩余假期时间,如果审核未通过,申请人不删除照样也会扣除时间
  649. */
  650. public function getqjsytime($uid, $type, $dt='', $id=0, $jzdt='')
  651. {
  652. $types = '增加'.$type.'';
  653. $wehe = "`kind`='$types'";
  654. if($type=='调休'){
  655. $types='加班';
  656. $wehe = "((`kind`='$types' and `jiatype`=0) or (`kind`='增加调休'))"; //只有可调休才能用
  657. }
  658. if($dt=='')$dt = $this->rock->now;
  659. if($jzdt=='')$jzdt = $dt; //截止时间
  660. $zto = $to1 = 0;
  661. $enddt = '';//截止
  662. //总
  663. $zrows = $this->db->getall("select * from `[Q]kqinfo` where `uid`='$uid' and `status`=1 and $wehe order by `stime` asc");
  664. if(!$zrows)return 0;
  665. foreach($zrows as $k1=>$rs1){
  666. $jsdt = $rs1['enddt'];
  667. if(isempt($jsdt))$jsdt = '2099-12-31 23:59:59';
  668. $zrows[$k1]['enddt'] = $jsdt;
  669. $zrows[$k1]['totals'] = floatval($rs1['totals']);
  670. }
  671. //用过的
  672. $yrows = $this->db->getall("select * from `[Q]kqinfo` where `uid`='$uid' and `kind`='请假' and `qjkind`='$type' and `status` not in(5) and `id`<>$id order by `stime` asc");
  673. return $this->getqjsytimess($zrows, $yrows, $dt, $jzdt);
  674. }
  675. private function getqjsytimess($zrows, $yrows, $dt, $jzdt)
  676. {
  677. $zross = array();
  678. $yross = array();
  679. $zsssj = 0;
  680. if($yrows && $zrows){
  681. foreach($zrows as $k1=>$rs1){
  682. $totals = floatval($rs1['totals']); //总可用时间
  683. foreach($yrows as $k2=>$rs2){
  684. $totaly = floatval($rs2['totals']);
  685. if($totaly>0 && $rs2['stime']>=$rs1['stime'] && $rs2['etime']<=$rs1['enddt']){
  686. $sys = $totaly - $totals;
  687. if($sys==0){
  688. $totals = 0;
  689. $yrows[$k2]['totals']= 0;
  690. }else if($sys>0){
  691. $yrows[$k2]['totals']= $sys;
  692. $totals = 0;
  693. }else{
  694. $totals = 0-$sys;
  695. $yrows[$k2]['totals'] = 0;
  696. }
  697. }
  698. if($totals ==0)break;//扣完了
  699. }
  700. if($totals>0){
  701. $rs1['totals'] = $totals;
  702. $zross[] = $rs1;
  703. }
  704. }
  705. //递归处理
  706. $zsssj = $this->getqjsytimess($zross, $yross, $dt, $jzdt);
  707. }else{
  708. if($zrows)foreach($zrows as $k1=>$rs1){
  709. if($rs1['stime']<=$dt && $rs1['enddt']>=$jzdt){
  710. $zsssj+=$rs1['totals'];
  711. }
  712. }
  713. }
  714. return $zsssj;
  715. }
  716. //总统计显示
  717. public function getqjsytimestr($uid=0, $dt='', $id=0)
  718. {
  719. if($uid==0)$uid = $this->adminid;
  720. $rows = $this->db->getall("select `kind` from `[Q]kqinfo` where `uid`='$uid' and `status`=1 and `kind` like '增加%' group by `kind`");
  721. $tx = $this->getqjsytime($uid, '调休', $dt, $id);
  722. $str = '';
  723. if($tx>0)$str = '可调休('.$tx.'小时)';
  724. foreach($rows as $k=>$rs){
  725. if($rs['kind']=='增加调休')continue;
  726. $type = str_replace('增加', '', $rs['kind']);
  727. $sj = $this->getqjsytime($uid, $type, $dt, $id);
  728. if($str!='')$str .= ',';
  729. $str .= ''.$type.'('.$sj.'小时)';
  730. }
  731. if($str=='')$str='无剩余假期';
  732. return $str;
  733. }
  734. /**
  735. * 判断这段时间是否可以申请请假
  736. */
  737. public function leavepan($uid, $qjkind, $start, $end, $totals, $id=0, $kind='')
  738. {
  739. $msg = '';
  740. if($kind=='')$kind = '请假';
  741. $sdf = $this->db->rows('[Q]kqinfo',"`uid`='$uid' and `status`<>5 and ((`stime`<='$start' and `etime`>='$start') or (`stime`<='$end' and `etime`>='$end') or (`stime`>='$start' and `etime`<='$end')) and `kind`='$kind' and `id`<>'$id' ");
  742. if($sdf > 0){
  743. $msg = '该时间段已申请过了';
  744. }
  745. if($kind=='加班')return $msg;
  746. $tsjia = '事假,病假';
  747. $tsjia = m('option')->getval('kqsqtype', $tsjia); //读取选项
  748. if($msg == '' && !$this->contain(','.$tsjia.',', ','.$qjkind.',')){
  749. $sy1 = $this->getqjsytime($uid, $qjkind, $start, $id, $end);
  750. if($sy1<0)$sy1=0;
  751. $totals = floatval($totals);
  752. if($totals>$sy1)$msg = '剩余['.$qjkind.']'.$sy1.'小时,不能申请,'.c('xinhu')->helpstr('kaoqin').'';
  753. }
  754. return $msg;
  755. }
  756. /**
  757. * 计算当月请假时间合计
  758. */
  759. public function getqjtotal($uid, $month)
  760. {
  761. $to = $this->getkqtotalsss($uid, $month,'请假');
  762. return $to;
  763. }
  764. /**
  765. * 计算当月加班时间合计
  766. */
  767. public function getjbtotal($uid, $month)
  768. {
  769. $to = $this->getkqtotalsss($uid, $month,'加班');
  770. return $to;
  771. }
  772. private function getkqtotalsss($uid, $month, $kind)
  773. {
  774. $ors = $this->db->getmou('[Q]kqinfo','sum(totals)as totals',"`status`=1 and `uid`=$uid and `stime` like '$month%' and `kind`='$kind'");
  775. $to = 0;
  776. if($ors)$to = $ors;
  777. return $to;
  778. }
  779. /**
  780. * 统计当前我考勤异常的状态
  781. */
  782. public function getkqtotal($uid, $month)
  783. {
  784. $sql = "SELECT state,count(1)stotal FROM `[Q]kqanay` where `dt` like '$month%' and `uid`=$uid and `iswork`=1 and `states` is null GROUP BY `state`";
  785. $rows = $this->db->getall($sql);
  786. $chidao = $zaotui = $weidk = 0;
  787. foreach($rows as $k=>$rs){
  788. if($rs['state']=='迟到')$chidao = $rs['stotal'];
  789. if($rs['state']=='早退')$zaotui = $rs['stotal'];
  790. if($rs['state']=='未打卡')$weidk= $rs['stotal'];
  791. }
  792. $dbts = $this->getsbdt($uid, $month);//上班天数
  793. return array(
  794. 'ysbtime' => $dbts[0],
  795. 'zsbtime' => $dbts[1],
  796. 'cidao' => $chidao,
  797. 'zaotui' => $zaotui,
  798. 'weidk' => $weidk,
  799. 'jiaban' => $this->getjbtotal($uid, $month),
  800. 'jiabans' => $this->getjiafee($uid, $month),
  801. 'leave' => $this->getqjtotal($uid, $month),
  802. );
  803. }
  804. /**
  805. * 获取默认某天应该上班时间段
  806. * 返回array(array('每天上班时间断'))
  807. */
  808. public function getsbarr($uid, $dt)
  809. {
  810. $arr = $this->getkqsj($uid, $dt, 1);
  811. $barr = array();
  812. foreach($arr as $k=>$rs){
  813. if(!isempt($rs['stime']) && !isempt($rs['etime']))$barr[] = $rs;
  814. }
  815. return $barr;
  816. }
  817. /**
  818. * 获取某个人某一天考勤状态[{stat}]
  819. */
  820. public function getsbanay($uid, $dt)
  821. {
  822. $ansy = $this->getanay($uid, $dt, $dt);
  823. $nates= array();
  824. if(isset($ansy[$dt])){
  825. $barr = $ansy[$dt];
  826. foreach($barr as $k=>$rs){
  827. $nates[$rs['ztname']] = $rs;
  828. }
  829. }
  830. $sbarr = $this->getsbarr($uid, $dt);
  831. foreach($sbarr as $k=>$rs){
  832. $state = '<font color=red>未打卡</font>';
  833. if(isset($nates[$rs['name']])){
  834. $ors = $nates[$rs['name']];
  835. $state = $this->getkqstate($ors);
  836. }
  837. $sbarr[$k]['state'] = $state;
  838. }
  839. return $sbarr;
  840. }
  841. /**
  842. * 获取某一天的打卡记录
  843. */
  844. public function getdkjl($uid, $dt)
  845. {
  846. $rows = $this->db->getall("select `dkdt` from `[Q]kqdkjl` where uid='$uid' and `dkdt` like '".$dt."%' order by `dkdt`");
  847. foreach($rows as $k=>$rs){
  848. $rows[$k]['dktime'] = substr($rs['dkdt'], 11);
  849. }
  850. return $rows;
  851. }
  852. /**
  853. * 考勤状态
  854. */
  855. public function getkqstate($rs)
  856. {
  857. $s = $rs['state'];
  858. $state = $rs['state'];
  859. $iswork = $rs['iswork'];
  860. $miaocn = '';
  861. if($rs['emiao']>0){
  862. $stssa = explode(':', $this->dtobj->sjdate($rs['emiao'],'H:i:s'));
  863. if($stssa[0]>0)$miaocn=''.$stssa[0].'时';
  864. $miaocn.=''.$stssa[1].'分'.$stssa[2].'秒';
  865. }
  866. $rs['miaocn'] = $miaocn;
  867. if($iswork==0 && $state == '未打卡')$s='休息日';
  868. if(!isempt($rs['miaocn'])){
  869. $s.='['.$rs['miaocn'].']';
  870. }
  871. if(!isempt($rs['time']))$s.='('.substr($rs['time'],11).')';
  872. if(!isempt($rs['states'])){
  873. $state = '正常';
  874. $s = $rs['states'];
  875. }
  876. if($state != '正常' && $iswork==1){
  877. if($s=='未打卡'){
  878. $s='<font color=red>'.$s.'</font>';
  879. }else{
  880. $s='<font color=blue>'.$s.'</font>';
  881. }
  882. }
  883. if($s=='休息日')$s='<font color=#888888>'.$s.'</font>';
  884. return $s;
  885. }
  886. /**
  887. * 获取默认某天应该上班时间段
  888. * 返回09:00-18:00
  889. */
  890. public function getsbstr($uid, $dt)
  891. {
  892. $barr = $this->getsbarr($uid, $dt);
  893. $stime = $etime = '';
  894. foreach($barr as $k=>$rs){
  895. if($rs['iskq']==1 && $rs['isxx']=='0'){
  896. if($stime=='')$stime = $rs['stime'];
  897. $etime = $rs['etime'];
  898. }
  899. }
  900. if($stime=='')$stime = '09:00:00';
  901. if($etime=='')$etime = '18:00:00';
  902. $stimes = $dt.' '.$stime;
  903. $etimes = $dt.' '.$etime;
  904. return array(
  905. 'stime' => $stimes,
  906. 'stimes' => strtotime($stimes),
  907. 'etime' => $etimes,
  908. 'etimes' => strtotime($etimes),
  909. );
  910. }
  911. /**
  912. * 每天上班时间断,返回8小时
  913. */
  914. public function getworktime($uid, $dt='')
  915. {
  916. if($dt=='')$dt = $this->rock->date;
  917. $dt = substr($dt, 0, 10);
  918. $to = floatval(m('option')->getval('kqsbtime', 0));
  919. if($to==0)$to = $this->getsbtime($uid, $dt.' 00:00:00', $dt.' 23:59:59', 1);
  920. if($to<=0)$to = 8;//默认1天上班时间8小时
  921. return $to;
  922. }
  923. /**
  924. * 根据时间间隔获取上班时间小时
  925. * $lx=0 计算请假时间 1算当前应上班时间
  926. */
  927. public function getsbtime($uid,$sdt, $edt, $lx=0)
  928. {
  929. $tot = 0;
  930. $sdt1 = strtotime($sdt);
  931. $edt1 = strtotime($edt);
  932. $dtsa = explode(' ', $sdt);
  933. $dts = $dtsa[0];
  934. $jg = $this->dtobj->datediff('d', $sdt, $edt);
  935. for($i=0; $i<$jg+1; $i++){
  936. if($i>0)$dts = $this->dtobj->adddate($dts, 'd', 1);
  937. if($lx==0)if($this->isworkdt($uid, $dts)==0)continue;//休息日就不用算了
  938. $arr = $this->getsbarr($uid, $dts);
  939. foreach($arr as $k=>$rs){
  940. $iskt = $rs['iskt'];
  941. if($rs['iskq']==1 && $rs['isxx']=='0'){
  942. $_sts = strtotime($dts.' '.$rs['stime']);
  943. $_ets = strtotime($dts.' '.$rs['etime']);
  944. //开始时间-1
  945. if($iskt=='2'){
  946. }
  947. //结束时间+1
  948. if($iskt=='1'){
  949. $dts2 = $this->dtobj->adddate($dts, 'd', 1);
  950. $_ets = strtotime($dts2.' '.$rs['etime']);
  951. }
  952. if($_sts<$sdt1)$_sts=$sdt1;
  953. if($_ets>$edt1)$_ets=$edt1;
  954. $_tisg = $_ets - $_sts;
  955. if($_tisg>0)$tot+=$_tisg;
  956. }
  957. }
  958. }
  959. return $tot / 3600;
  960. }
  961. /**
  962. * 统计月份应上班天数
  963. * return array(应上班天数, 有上班天数);
  964. */
  965. public function getsbdt($uid, $month)
  966. {
  967. $month = substr($month, 0, 7);
  968. $dtobj = c('date');
  969. $max = $dtobj->getmaxdt($month);
  970. $startdt= ''.$month.'-01';
  971. $enddt = ''.$month.'-'.$max.'';
  972. $tian = 0; //应上班
  973. $ysb = 0; //已上班
  974. //$anayarr= $this->db->getrows('[Q]kqanay', "`uid`=$uid and `dt` like '$month%'");
  975. $sbxs = $this->getworktime($uid); //每天上班时间
  976. $starr = $this->db->getall("SELECT `dt`,sum(timesb)as timesb,sum(timeys)as timeys FROM `[Q]kqanay` where `uid`=$uid and `dt` like '$month%' and `iswork`=1 GROUP BY dt");
  977. foreach($starr as $k=>$rs){
  978. $timesb = floatval($rs['timesb']);
  979. $timeys = floatval($rs['timeys']);
  980. $tian += round($timesb/$sbxs,1);
  981. $ysb += round($timeys/$sbxs, 1);
  982. }
  983. /*
  984. for($i=0; $i<$max; $i++){
  985. $oi = ($i<10) ? '0'.$i.'' : $i;
  986. $dt = ''.$month.'-'.$oi.'';
  987. if($this->isworkdt($uid, $dt)==1){
  988. $tian++;
  989. foreach($anayarr as $k=>$rs){
  990. if($rs['dt']==$dt && $rs['state']!='未打卡'){
  991. $ysb++;
  992. break;
  993. }
  994. }
  995. }
  996. }*/
  997. //$this->rock->number
  998. return array(round($tian,1), round($ysb,1), round($tian-$ysb,1));
  999. }
  1000. /**
  1001. * 计算人员加班工资,一天默认8小时
  1002. * $uid 人员,$hour 小时,$stime 加班开始时间
  1003. * 加班费计算(正常工作日1.5),周末2.0,节假日3.0
  1004. * 上月的(基本工资+职位津贴+技能津贴)/本月应上班天数 * 1.5,周末*2.0
  1005. */
  1006. public function jiafee($uid, $hour, $stime)
  1007. {
  1008. $fee = 0;
  1009. $hour= floatval($hour);
  1010. if($hour<=0)return $fee;
  1011. $nrs = $this->db->getone('[Q]hrsalary','`xuid`='.$uid.' and `status`<>5','`base`,`postjt`,`skilljt`','`month` desc');
  1012. if($nrs){
  1013. $dt = substr($stime, 0, 10);
  1014. $hs = $this->getworktime($uid, $dt); //一天上班小时
  1015. $sbarr = $this->getsbdt($uid, $dt);
  1016. $bsh = 1.5;
  1017. if($this->isworkdt($uid, $dt)==0)$bsh = 2; //休息日倍数2
  1018. $base = floatval($nrs['base']) + floatval($nrs['postjt']) + floatval($nrs['skilljt']);
  1019. $gongzi = $base/$sbarr[0];//一天的工资
  1020. $fee = ($gongzi / $hs) * $bsh * $hour;
  1021. $fee = $this->rock->number($fee);
  1022. }
  1023. return $fee;
  1024. }
  1025. //获取对应月份加班费
  1026. public function getjiafee($uid, $month)
  1027. {
  1028. $mond = $this->db->getmou('[Q]kqinfo','sum(jiafee)', "`uid`=$uid and `kind`='加班' and `status`=1 and `jiatype`=1 and `stime` like '$month%'");
  1029. if(isempt($mond))$mond = 0;
  1030. return $mond;
  1031. }
  1032. /**
  1033. * all统计
  1034. */
  1035. public function alltotal($month, $uids)
  1036. {
  1037. $barr = $this->alltotalrows($month, $uids);
  1038. $data = $barr['rows'][0];
  1039. $farrs = $barr['columns'];
  1040. $farrs['未打卡'] = 'weidk';
  1041. $farrs['请假'] = 'qingjia';
  1042. $farrs['加班'] = 'jiaban';
  1043. $farrs['外出出差'] = 'outci';
  1044. $farrs['打卡异常'] = 'errci';
  1045. $farrs['应上班'] = 'sbday';
  1046. $farrs['已上班'] = 'ysbday';
  1047. return array('data'=>$data, 'fields'=>$farrs, 'unita'=> array(
  1048. 'qingjia' => '小时',
  1049. 'jiaban' => '小时',
  1050. 'sbday' => '天',
  1051. 'ysbday' => '天',
  1052. ));
  1053. }
  1054. /**
  1055. * 考勤统计使用
  1056. */
  1057. private function alltotalrowssst($rows,$dt, $oi=0)
  1058. {
  1059. $columns= array();
  1060. if(!isset($rows[$oi]))return $columns;
  1061. $fuid = $rows[$oi]['id'];
  1062. $farrs = $this->getkqztarr($fuid, $dt);
  1063. $columns= $farrs;
  1064. if($columns)return $columns;
  1065. return $this->alltotalrowssst($rows, $dt, $oi+1);
  1066. }
  1067. public function alltotalrows($month, $uids)
  1068. {
  1069. $rows = array();
  1070. if(is_array($uids)){
  1071. $rows = $uids;
  1072. }else{
  1073. $uidsa = explode(',', $uids);
  1074. foreach($uidsa as $_uids)$rows[] = array('id'=>$_uids);
  1075. }
  1076. $uids = '0';
  1077. foreach($rows as $k=>$rs)$uids.=','.$rs['id'].'';
  1078. $farrs = $columns = array();
  1079. //获取考勤状态数组{'正常':'state0'}
  1080. if($rows)$columns= $this->alltotalrowssst($rows, $month.'-01'); //读取表头
  1081. $darr = $this->db->getall("SELECT uid,state,states FROM `[Q]kqanay` where `uid` in($uids) and dt like '$month%' and iswork=1");
  1082. $sarr = array();
  1083. foreach($darr as $k=>$rs){
  1084. $state = $rs['state'];
  1085. $uid = $rs['uid'];
  1086. if(!isempt($rs['states']))$state='正常';
  1087. if(!isset($sarr[$uid]))$sarr[$uid]=array();
  1088. if(!isset($sarr[$uid][$state]))$sarr[$uid][$state]=0;
  1089. $sarr[$uid][$state]++; //统计次数用的
  1090. }
  1091. $farrs = $columns;
  1092. $farrs['未打卡'] = 'weidk';
  1093. $farrs['请假'] = 'qingjia';
  1094. $farrs['事假'] = 'shijia';
  1095. $farrs['加班'] = 'jiaban';
  1096. $lxarr = m('option')->getmnum('kqqjkind');
  1097. foreach($lxarr as $k=>$rs){
  1098. $tev = 'qingjia'.$rs['id'].'';
  1099. $farrs[$rs['name']] = $tev;
  1100. //$columns[$rs['name']] = $tev;
  1101. }
  1102. $kqarr = $this->db->getall("select sum(totals)as totals,kind,qjkind,uid from `[Q]kqinfo` where `status`=1 and `uid` in($uids) and `stime` like '$month%' and `kind` in('请假','加班') group by `uid`,`qjkind`");
  1103. foreach($kqarr as $k=>$rs){
  1104. $uid = $rs['uid'];
  1105. $kind = $rs['qjkind'];
  1106. if(isempt($kind))$kind = '加班';
  1107. if(!isset($sarr[$uid]))$sarr[$uid]=array();
  1108. $sarr[$uid][$kind] = $rs['totals'];
  1109. $kinds = $kind.'(时)';
  1110. if($rs['kind']=='请假' && !isset($columns[$kinds])){
  1111. $columns[$kinds] = $farrs[$kind];
  1112. }
  1113. }
  1114. foreach($rows as $k=>$rs){
  1115. $uid = $rs['id'];
  1116. if(isset($sarr[$uid])){
  1117. foreach($sarr[$uid] as $zt=>$v){
  1118. if(isset($farrs[$zt])){
  1119. $rows[$k][$farrs[$zt]] = $v;
  1120. }
  1121. }
  1122. }
  1123. $outci = $this->db->rows('[Q]kqout',"`status`=1 and `uid`=$uid and `outtime` like '$month%'");
  1124. if($outci==0)$outci='';
  1125. $rows[$k]['outci'] = $outci;
  1126. $errci = $this->db->rows('[Q]kqerr',"`status`=1 and `uid`=$uid and `dt` like '$month%'");
  1127. if($errci==0)$errci='';
  1128. $rows[$k]['errci'] = $errci;
  1129. $sbdt = $this->getsbdt($uid, $month);
  1130. $rows[$k]['sbday'] = $sbdt[0];
  1131. $rows[$k]['ysbday'] = $sbdt[1]>0 ? $sbdt[1] : '';
  1132. }
  1133. return array('rows'=>$rows,'columns'=>$columns);
  1134. }
  1135. }
粤ICP备19079148号