EngineerSettlementPermanentlyLogic.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | likeadmin快速开发前后端分离管理后台(PHP版)
  4. // +----------------------------------------------------------------------
  5. // | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
  6. // | 开源版本可自由商用,可去除界面版权logo
  7. // | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
  8. // | github下载:https://github.com/likeshop-github/likeadmin
  9. // | 访问官网:https://www.likeadmin.cn
  10. // | likeadmin团队 版权所有 拥有最终解释权
  11. // +----------------------------------------------------------------------
  12. // | author: likeadminTeam
  13. // +----------------------------------------------------------------------
  14. namespace app\adminapi\logic\master_worker;
  15. use app\common\model\dict\DictData;
  16. use app\common\model\master_worker\EngineerSettlementPermanently;
  17. use app\common\logic\BaseLogic;
  18. use app\common\model\master_worker\MasterWorker;
  19. use app\common\model\master_worker\SalaryItemPermanently;
  20. use app\common\model\works\ServiceWork;
  21. use DateTime;
  22. use think\facade\Db;
  23. use think\facade\Log;
  24. /**
  25. * EngineerSettlementPermanently逻辑
  26. * Class EngineerSettlementPermanentlyLogic
  27. * @package app\adminapi\logic
  28. */
  29. class EngineerSettlementPermanentlyLogic extends BaseLogic
  30. {
  31. protected static int $conf_step_days = 7;
  32. protected static string $conf_days = '2025-06-09 23:59:59';
  33. /**
  34. * @notes 添加
  35. * @param array $params
  36. * @return bool
  37. * @author likeadmin
  38. * @date 2025/06/09 10:33
  39. */
  40. public static function add(array $params): bool
  41. {
  42. Db::startTrans();
  43. try {
  44. EngineerSettlementPermanently::create([
  45. 'master_worker_id' => $params['master_worker_id'],
  46. 'last_settlement_time' => $params['last_settlement_time'],
  47. 'settlement_time' => $params['settlement_time'],
  48. 'step_days' => $params['step_days'],
  49. 'status' => $params['status'],
  50. 'admin_id' => $params['admin_id'],
  51. 'remark' => $params['remark']
  52. ]);
  53. Db::commit();
  54. return true;
  55. } catch (\Exception $e) {
  56. Db::rollback();
  57. self::setError($e->getMessage());
  58. return false;
  59. }
  60. }
  61. /**
  62. * @notes 编辑
  63. * @param array $params
  64. * @return bool
  65. * @author likeadmin
  66. * @date 2025/06/09 10:33
  67. */
  68. public static function edit(array $params): bool
  69. {
  70. //Db::startTrans();
  71. try {
  72. /*EngineerSettlementPermanently::where('id', $params['id'])->update([
  73. 'amount' => $params['amount']??0,
  74. 'payment_time' => $params['payment_time']??'',
  75. 'deduction_amount' => $params['deduction_amount']??0,
  76. 'deduction_describe' => $params['deduction_describe']??'',
  77. 'status' => 1,
  78. 'admin_id' => $params['admin_id']??0,
  79. 'remark' => $params['remark']??''
  80. ]);*/
  81. if(self::settlement($params)){
  82. throw new \Exception(self::getError());
  83. }
  84. //Db::commit();
  85. return true;
  86. } catch (\Exception $e) {
  87. //Db::rollback();
  88. self::setError($e->getMessage());
  89. return false;
  90. }
  91. }
  92. /**
  93. * @notes 删除
  94. * @param array $params
  95. * @return bool
  96. * @author likeadmin
  97. * @date 2025/06/09 10:33
  98. */
  99. public static function delete(array $params): bool
  100. {
  101. return EngineerSettlementPermanently::destroy($params['id']);
  102. }
  103. /**
  104. * @notes 获取详情
  105. * @param $params
  106. * @return array
  107. * @author likeadmin
  108. * @date 2025/06/09 10:33
  109. */
  110. public static function detail($params): array
  111. {
  112. function getAllSalary($salaryItemPermanently): float {
  113. $all_salary = 0.00;
  114. foreach ($salaryItemPermanently as $item) {
  115. $all_salary += $item['term_amount'];
  116. }
  117. return $all_salary;
  118. }
  119. $item = EngineerSettlementPermanently::with(['bankAccount','workerInfo','salaryItemPermanently'])->findOrEmpty($params['id'])->toArray();
  120. $item['all_salary'] = getAllSalary($item['salaryItemPermanently']);
  121. return $item;
  122. }
  123. /**
  124. * @notes 执行结算
  125. * @param $params
  126. * @author likeadmin
  127. * @date 2025/06/09 10:33
  128. */
  129. public static function settlement($params)
  130. {
  131. Db::startTrans();
  132. try {
  133. $settlementPermanently = EngineerSettlementPermanently::where('id', $params['id'])->findOrEmpty();
  134. if($settlementPermanently->isEmpty()){
  135. throw new \Exception('结算记录不存在');
  136. }
  137. //$amount = SalaryItemPermanently::where('permanently_settlement_id', $params['id'])->sum('term_amount');
  138. $settlementPermanently->payment_time = $params['payment_time']?:date('Y-m-d', time());
  139. $settlementPermanently->deduction_amount = $params['deduction_amount']??0;
  140. $settlementPermanently->deduction_describe = $params['deduction_describe']??'';
  141. $settlementPermanently->remark = $params['remark']??'';
  142. $settlementPermanently->status = 1;
  143. $settlementPermanently->admin_id = $params['admin_id']??0;
  144. $settlementPermanently->amount = $params['amount']??0;
  145. $settlementPermanently->save();
  146. Db::commit();
  147. // 删除该日期步进天数内的之前的快照
  148. /*$ids = EngineerSettlementPermanently::where('status',0)->
  149. where('settlement_time','between',[$settlementPermanently->last_settlement_time,$settlementPermanently->settlement_time])->column('id')??[];
  150. if(!empty($ids)){
  151. EngineerSettlementPermanently::where('id',$ids)->delete();
  152. SalaryItemPermanently::where('permanently_settlement_id',$ids)->delete();
  153. }*/
  154. return true;
  155. } catch (\Exception $e) {
  156. Db::rollback();
  157. self::setError($e->getMessage());
  158. return false;
  159. }
  160. }
  161. public static function getLastSettlementTime($master_worker_id,$conf_step_days = 7,$conf_days = null)
  162. {
  163. //查询该工程师上个结算日期
  164. $last_settlement_time = EngineerSettlementPermanently::where('master_worker_id',$master_worker_id)->where('status',1)->order('settlement_time','desc')->value('settlement_time');
  165. if(empty($last_settlement_time) || $last_settlement_time === '0000-00-00'){
  166. return strtotime($conf_days);
  167. }
  168. $current_time = strtotime(date("Y-m-d",time()));
  169. $last_st_time = $current_time - ($conf_step_days * 86400);
  170. if(strtotime($last_settlement_time) < $last_st_time){
  171. return $last_st_time;
  172. }else{
  173. return strtotime($last_settlement_time);
  174. }
  175. }
  176. /**
  177. * @notes 定时任务 - 每天
  178. * @author likeadmin
  179. * @date 2025/06/09 10:33
  180. */
  181. public static function settlementRegular($masterWorker_id = 0)
  182. {
  183. Db::startTrans();
  184. try {
  185. $wh = ['type' => 2];
  186. $masterWorker_id && $wh['id'] = $masterWorker_id;
  187. //$masterWorker_id
  188. // audit_state = 1
  189. $masterWorkers = MasterWorker::where($wh)->select()->toArray();
  190. foreach ($masterWorkers as $masterWorker) {
  191. $last_settlement_time = self::getLastSettlementTime($masterWorker['id']);
  192. $settlement_time = strtotime(date("Y-m-d",time())) + 86399;
  193. $data = [
  194. 'master_worker_id' => $masterWorker['id'],
  195. 'last_settlement_time' => date('Y-m-d',$last_settlement_time),
  196. 'settlement_time' => date('Y-m-d',$settlement_time),
  197. 'step_days' => self::$conf_step_days,
  198. 'status' => 0,
  199. 'admin_id' => 0,
  200. 'remark' => ''
  201. ];
  202. $wh = ['master_worker_id' => $masterWorker['id'],'settlement_time' => date('Y-m-d',$settlement_time),
  203. 'step_days' => self::$conf_step_days, 'status' => 0];
  204. $info = EngineerSettlementPermanently::where($wh)->findOrEmpty();
  205. if($info->isEmpty()){
  206. $settlementPermanently = EngineerSettlementPermanently::create($data);
  207. }else{
  208. EngineerSettlementPermanently::where($wh)->where('id',$info->id)->update($data);
  209. $settlementPermanently['id'] = $info->id;
  210. }
  211. /*$settlementPermanently = EngineerSettlementPermanently::create([
  212. 'master_worker_id' => $masterWorker['id'],
  213. 'last_settlement_time' => date('Y-m-d',$last_settlement_time),
  214. 'settlement_time' => date('Y-m-d',$settlement_time),
  215. 'step_days' => self::$conf_step_days,
  216. 'status' => 0,
  217. 'admin_id' => 0,
  218. 'remark' => ''
  219. ]);*/
  220. //$settlementPermanently->id
  221. $salary_item_data = DictData::where('type_value','salary_item')->column('name','value');
  222. $salaryItemPermanently = new SalaryItemPermanently();
  223. foreach ($salary_item_data as $salary_item => $item_name) {
  224. $fu_name = 'salary_item_'.$salary_item;
  225. if(!method_exists(SalaryItemPermanently::class,$fu_name)){
  226. continue;
  227. }
  228. $salaryItemPermanently->$fu_name($settlementPermanently['id'],$masterWorker['id'],[
  229. 'start_time'=>$last_settlement_time,
  230. 'end_time'=>$settlement_time,
  231. 'step_days'=>self::$conf_step_days,'item_name'=>$item_name
  232. ]);
  233. }
  234. }
  235. Db::commit();
  236. return true;
  237. } catch (\Exception $e) {
  238. Db::rollback();
  239. self::setError($e->getFile().':'.$e->getLine().':'.$e->getMessage());
  240. return false;
  241. }
  242. }
  243. /**
  244. * @notes 定时任务 - 每周
  245. * @author likeadmin
  246. * @date 2025/06/09 10:33
  247. */
  248. public static function settlementRegularWeek($masterWorker_id = 0)
  249. {
  250. try {
  251. // 限制每周一才能结算上周
  252. if(date("w") != 1) return false;
  253. // 兼职工程师-每周 period_type = 2
  254. self::partTimeMaster($masterWorker_id,2);
  255. // 保单工程师-每周 period_type = 2
  256. self::longTermMaster($masterWorker_id,2);
  257. return true;
  258. } catch (\Exception $e) {
  259. self::setError($e->getFile().':'.$e->getLine().':'.$e->getMessage());
  260. return false;
  261. }
  262. }
  263. /**
  264. * @notes 定时任务 - 每月
  265. * @author likeadmin
  266. * @date 2025/06/09 10:33
  267. */
  268. public static function settlementRegularManth($masterWorker_id = 0)
  269. {
  270. try {
  271. // 限制每月一才能结算上月
  272. if((int)date("d") != 1) return false;
  273. // 保单工程师 period_type = 3
  274. self::longTermMaster($masterWorker_id,3);
  275. // 全职工程师
  276. self::fullTimeMaster($masterWorker_id,3);
  277. return true;
  278. } catch (\Exception $e) {
  279. self::setError($e->getFile().':'.$e->getLine().':'.$e->getMessage());
  280. return false;
  281. }
  282. }
  283. public static function partTimeMaster($masterWorker_id = 0,$period_type = 0)
  284. {
  285. //Db::startTrans();
  286. try {
  287. $master_type = 1;
  288. $wh = [['type', '=', $master_type]];
  289. $mwids = ServiceWork::where('service_status',3)->where('finished_time','between',[time() - 65*86400,time()])->column('master_worker_id')??[];
  290. if(!empty($mwids)) $wh[] = ['id','in', array_values(array_unique($mwids))];
  291. $masterWorker_id && $wh[] = ['id','=',$masterWorker_id];
  292. // 获取上周的周一开始与周末结束时间
  293. $period_type == 2 && list($startTime,$endTime) = self::lastWeekTime();
  294. $period_type == 3 && list($startTime,$endTime) = self::lastManthTime();
  295. $conf_step_days = 0;
  296. $period_type == 2 && $conf_step_days = 7;
  297. $period_type == 3 && $conf_step_days = 30;
  298. //$masterWorker_id
  299. // audit_state = 1
  300. $masterWorkers = MasterWorker::where($wh)->select()->toArray();
  301. foreach ($masterWorkers as $masterWorker) {
  302. $last_settlement_time = $startTime;
  303. $settlement_time = $endTime;
  304. $data = [
  305. "period_type"=>$period_type,"master_type"=>$master_type,
  306. 'master_worker_id' => $masterWorker['id'],
  307. 'last_settlement_time' => date('Y-m-d',$last_settlement_time),
  308. 'settlement_time' => date('Y-m-d',$settlement_time),
  309. 'step_days' => $conf_step_days,
  310. 'status' => 0,
  311. 'admin_id' => 0,
  312. 'remark' => ''
  313. ];
  314. $wh = ["period_type"=>$period_type,"master_type"=>$master_type,'master_worker_id' => $masterWorker['id'],'settlement_time' => date('Y-m-d',$settlement_time), 'status' => 0];
  315. $info = EngineerSettlementPermanently::where($wh)->findOrEmpty();
  316. if($info->isEmpty()){
  317. $settlementPermanently = EngineerSettlementPermanently::create($data);
  318. }else{
  319. EngineerSettlementPermanently::where($wh)->where('id',$info->id)->update($data);
  320. $settlementPermanently['id'] = $info->id;
  321. }
  322. $salary_item_data = DictData::where('type_value','salary_item')->column('name','value');
  323. $salaryItemPermanently = new SalaryItemPermanently();
  324. foreach ($salary_item_data as $salary_item => $item_name) {
  325. $fu_name = 'salary_item_'.$salary_item;
  326. if(!method_exists(SalaryItemPermanently::class,$fu_name)){
  327. continue;
  328. }
  329. $salaryItemPermanently->$fu_name($settlementPermanently['id'],$masterWorker['id'],[
  330. "period_type"=>$period_type,"master_type"=>$master_type,
  331. 'start_time'=>$last_settlement_time,
  332. 'end_time'=>$settlement_time,
  333. 'step_days'=>$conf_step_days,'item_name'=>$item_name
  334. ]);
  335. }
  336. }
  337. //Db::commit();
  338. return true;
  339. } catch (\Exception $e) {
  340. //Db::rollback();
  341. self::setError($e->getFile().':'.$e->getLine().':'.$e->getMessage());
  342. return false;
  343. }
  344. }
  345. public static function longTermMaster($masterWorker_id = 0,$period_type = 0)
  346. {
  347. //Db::startTrans();
  348. try {
  349. $master_type = 2;
  350. $wh = [['type', '=', $master_type]];
  351. $mwids = ServiceWork::where('service_status',3)->where('finished_time','between',[time() - 65*86400,time()])->column('master_worker_id')??[];
  352. if(!empty($mwids)) $wh[] = ['id','in', array_values(array_unique($mwids))];
  353. $masterWorker_id && $wh[] = ['id','=',$masterWorker_id];
  354. // 获取上周的周一开始与周末结束时间
  355. $period_type == 2 && list($startTime,$endTime) = self::lastWeekTime();
  356. $period_type == 3 && list($startTime,$endTime) = self::lastManthTime();
  357. $conf_step_days = 0;
  358. $period_type == 2 && $conf_step_days = 7;
  359. $period_type == 3 && $conf_step_days = 30;
  360. //$masterWorker_id
  361. // audit_state = 1
  362. $masterWorkers = MasterWorker::where($wh)->select()->toArray();
  363. foreach ($masterWorkers as $masterWorker) {
  364. $last_settlement_time = $startTime;
  365. $settlement_time = $endTime;
  366. $data = [
  367. "period_type"=>$period_type,"master_type"=>$master_type,
  368. 'master_worker_id' => $masterWorker['id'],
  369. 'last_settlement_time' => date('Y-m-d',$last_settlement_time),
  370. 'settlement_time' => date('Y-m-d',$settlement_time),
  371. 'step_days' => $conf_step_days,
  372. 'status' => 0,
  373. 'admin_id' => 0,
  374. 'remark' => ''
  375. ];
  376. $wh = ["period_type"=>$period_type,"master_type"=>$master_type,'master_worker_id' => $masterWorker['id'],'settlement_time' => date('Y-m-d',$settlement_time), 'status' => 0];
  377. $info = EngineerSettlementPermanently::where($wh)->findOrEmpty();
  378. if($info->isEmpty()){
  379. $settlementPermanently = EngineerSettlementPermanently::create($data);
  380. }else{
  381. EngineerSettlementPermanently::where($wh)->where('id',$info->id)->update($data);
  382. $settlementPermanently['id'] = $info->id;
  383. }
  384. $salary_item_data = DictData::where('type_value','salary_item')->column('name','value');
  385. $salaryItemPermanently = new SalaryItemPermanently();
  386. foreach ($salary_item_data as $salary_item => $item_name) {
  387. $fu_name = 'salary_item_'.$salary_item;
  388. if(!method_exists(SalaryItemPermanently::class,$fu_name)){
  389. continue;
  390. }
  391. $salaryItemPermanently->$fu_name($settlementPermanently['id'],$masterWorker['id'],[
  392. "period_type"=>$period_type,"master_type"=>$master_type,
  393. 'start_time'=>$last_settlement_time,
  394. 'end_time'=>$settlement_time,
  395. 'step_days'=>$conf_step_days,'item_name'=>$item_name
  396. ]);
  397. }
  398. }
  399. //Db::commit();
  400. return true;
  401. } catch (\Exception $e) {
  402. //Db::rollback();
  403. self::setError($e->getFile().':'.$e->getLine().':'.$e->getMessage());
  404. return false;
  405. }
  406. }
  407. public static function fullTimeMaster($masterWorker_id = 0,$period_type = 0)
  408. {
  409. //Db::startTrans();
  410. try {
  411. $master_type = 3;
  412. $wh = [['type', '=', $master_type]];
  413. $mwids = ServiceWork::where('service_status',3)->where('finished_time','between',[time() - 65*86400,time()])->column('master_worker_id')??[];
  414. if(!empty($mwids)) $wh[] = ['id','in', array_values(array_unique($mwids))];
  415. $masterWorker_id && $wh[] = ['id','=',$masterWorker_id];
  416. // 获取上周的周一开始与周末结束时间
  417. $period_type == 2 && list($startTime,$endTime) = self::lastWeekTime();
  418. $period_type == 3 && list($startTime,$endTime) = self::lastManthTime();
  419. $conf_step_days = 0;
  420. $period_type == 2 && $conf_step_days = 7;
  421. $period_type == 3 && $conf_step_days = 30;
  422. //$masterWorker_id
  423. // audit_state = 1
  424. $masterWorkers = MasterWorker::where($wh)->select()->toArray();
  425. foreach ($masterWorkers as $masterWorker) {
  426. $last_settlement_time = $startTime;
  427. $settlement_time = $endTime;
  428. $data = [
  429. "period_type"=>$period_type,"master_type"=>$master_type,
  430. 'master_worker_id' => $masterWorker['id'],
  431. 'last_settlement_time' => date('Y-m-d',$last_settlement_time),
  432. 'settlement_time' => date('Y-m-d',$settlement_time),
  433. 'step_days' => $conf_step_days,
  434. 'status' => 0,
  435. 'admin_id' => 0,
  436. 'remark' => ''
  437. ];
  438. $wh = ["period_type"=>$period_type,"master_type"=>$master_type,'master_worker_id' => $masterWorker['id'],'settlement_time' => date('Y-m-d',$settlement_time), 'status' => 0];
  439. $info = EngineerSettlementPermanently::where($wh)->findOrEmpty();
  440. if($info->isEmpty()){
  441. $settlementPermanently = EngineerSettlementPermanently::create($data);
  442. }else{
  443. EngineerSettlementPermanently::where($wh)->where('id',$info->id)->update($data);
  444. $settlementPermanently['id'] = $info->id;
  445. }
  446. $salary_item_data = DictData::where('type_value','salary_item')->column('name','value');
  447. $salaryItemPermanently = new SalaryItemPermanently();
  448. foreach ($salary_item_data as $salary_item => $item_name) {
  449. $fu_name = 'salary_item_'.$salary_item;
  450. if(!method_exists(SalaryItemPermanently::class,$fu_name)){
  451. continue;
  452. }
  453. $salaryItemPermanently->$fu_name($settlementPermanently['id'],$masterWorker['id'],[
  454. "period_type"=>$period_type,"master_type"=>$master_type,
  455. 'start_time'=>$last_settlement_time,
  456. 'end_time'=>$settlement_time,
  457. 'step_days'=>$conf_step_days,'item_name'=>$item_name
  458. ]);
  459. }
  460. }
  461. //Db::commit();
  462. return true;
  463. } catch (\Exception $e) {
  464. //Db::rollback();
  465. self::setError($e->getFile().':'.$e->getLine().':'.$e->getMessage());
  466. return false;
  467. }
  468. }
  469. public static function lastWeekTime()
  470. {
  471. $today = new DateTime('today');
  472. $last_week_monday = clone $today;
  473. $last_week_monday->modify('this week -7 days')->setTime(0, 0, 0);
  474. $last_week_sunday = clone $last_week_monday;
  475. $last_week_sunday->modify('+6 days');
  476. $last_week_start = $last_week_monday->getTimestamp(); // 上周一零点时间戳
  477. $last_week_end = $last_week_sunday->getTimestamp()+86399; // 上周日零点时间戳
  478. return [$last_week_start,$last_week_end];
  479. /*return [
  480. 'startTime' => $last_week_start,
  481. 'endTime' => $last_week_end
  482. ];*/
  483. }
  484. public static function lastManthTime()
  485. {
  486. $today = new DateTime('today');
  487. $firstDayOfThisMonth = clone $today;
  488. $firstDayOfThisMonth->modify('first day of this month')->setTime(0, 0, 0); // 本月第一天
  489. $lastDayOfLastMonth = clone $firstDayOfThisMonth;
  490. $lastDayOfLastMonth->modify('-1 second'); // 上个月的最后一天
  491. $firstDayOfLastMonth = clone $firstDayOfThisMonth;
  492. $firstDayOfLastMonth->modify('-1 month')->setTime(0, 0, 0); // 上个月的第一天
  493. $last_manth_start = $firstDayOfLastMonth->getTimestamp();
  494. $last_manth_end = $lastDayOfLastMonth->getTimestamp();
  495. return [$last_manth_start,$last_manth_end];
  496. /*return [
  497. 'startTime' => $last_manth_start,
  498. 'endTime' => $last_manth_end
  499. ];*/
  500. }
  501. }