kaoqinModel.php 35 KB

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