Achievement.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. <?php
  2. namespace addons\qingdongams\controller;
  3. use addons\qingdongams\model\Achievement as AchievementModel;
  4. use addons\qingdongams\model\AchievementRecords;
  5. use addons\qingdongams\model\Contract;
  6. use addons\qingdongams\model\Customer;
  7. use addons\qingdongams\model\ExamineRecord;
  8. use addons\qingdongams\model\Flow;
  9. use addons\qingdongams\model\Message;
  10. use addons\qingdongams\model\StaffDepartment;
  11. use addons\qingdongams\model\Staff;
  12. use addons\qingdongams\model\Receivables;
  13. use addons\qingdongams\model\Event;
  14. use addons\qingdongams\model\StaffTeam;
  15. use addons\qingdongams\model\Workorder;
  16. use think\Db;
  17. use think\Exception;
  18. /**
  19. * @desc 操作文档:https://doc.fastadmin.net/qingdongams
  20. * @desc 软件介绍:https://www.fastadmin.net/store/qingdongams.html
  21. * @desc 售后微信:qingdong_crm
  22. */
  23. /**
  24. * 业绩管理接口
  25. */
  26. class Achievement extends StaffApi
  27. {
  28. protected $noNeedLogin = [];
  29. protected $noNeedRight = [];
  30. public function _initialize()
  31. {
  32. parent::_initialize();
  33. try{
  34. \think\Db::execute("SET @@sql_mode='';");
  35. }catch (Exception $e){
  36. }
  37. }
  38. //部门列表
  39. public function getDepartment()
  40. {
  41. $department = StaffDepartment::where([])->field('id,name')->select();
  42. $start = 2020;
  43. $end = date('Y');
  44. for ($start; $start <= $end; $start++) {
  45. if ($start == $end) {
  46. $years[] = [
  47. 'id' => $start,
  48. 'name' => $start . '年',
  49. 'selected' => 'selected'
  50. ];
  51. } else {
  52. $years[] = [
  53. 'id' => $start,
  54. 'name' => $start . '年',
  55. ];
  56. }
  57. }
  58. $department = array_merge([['id' => 0, 'name' => '全部']], $department);
  59. $this->success('请求成功', ['department' => $department, 'years' => $years]);
  60. }
  61. //获取员工业绩目标列表
  62. public function getStaffList()
  63. {
  64. $department_id = input('department_id');
  65. $year = input('year', date('Y'), 'intval');
  66. $status = input('status', 1);//1获客 2拜访 3业绩 4回款 5工单
  67. $where = [];
  68. if ($department_id) {
  69. $where['department_id'] = $department_id;
  70. }
  71. $where['status'] = 1;
  72. $staffModel = new Staff();
  73. $with = [ 'achievement' => function ($query) use ($year, $status) {
  74. $query->where(['year' => $year, 'status' => $status])->field('yeartarget,obj_id');
  75. }];
  76. if ($status == 1) {//获客
  77. $with['customer'] = function ($query) use ($year) {
  78. //客户
  79. $query->where(['createtime' => ['between', [strtotime($year . '-1-1'), strtotime($year . '-12-31')]]]);
  80. };
  81. } elseif ($status == 2) {//拜访
  82. $with['visit'] = function ($query) use ($year) {
  83. //合同签署日期
  84. $query->where(['createtime' => ['between', [strtotime($year . '-1-1'), strtotime($year . '-12-31')]]]);
  85. };
  86. } elseif ($status == 3) {//业绩
  87. $with['contract'] = function ($query) use ($year) {
  88. //合同签署日期
  89. $query->where(['order_date' => ['between', [$year . '-1-1', $year . '-12-31']]]);
  90. };
  91. } elseif ($status == 4) {//回款
  92. $with['receivables'] = function ($query) use ($year) {
  93. //回款日期
  94. $query->where(['return_time' => ['between', [$year . '-1-1', $year . '-12-31']]]);
  95. };
  96. } elseif ($status == 5) {//工单
  97. $with['workorder'] = function ($query) use ($year) {
  98. //回款日期
  99. $query->where(['createtime' => ['between', [strtotime($year . '-1-1'), strtotime($year . '-12-31')]]]);
  100. };
  101. }
  102. $staffs = $staffModel->where($where)->field('id,name,img,post')->with($with)->select();
  103. foreach ($staffs as $k => $v) {
  104. if (empty($v['achievement'])) {
  105. $v['achievement'] = ['yeartarget' => 0];
  106. }
  107. $v['ratio'] = getRatio($v['achieve'], $v['achievement']['yeartarget']);
  108. $staffs[$k] = $v;
  109. }
  110. $this->success('请求成功', $staffs);
  111. }
  112. //获取员工业绩目标详情
  113. public function getStaffDetail()
  114. {
  115. $staff_id = input('staff_id');
  116. $year = input('year', date('Y'), 'intval');
  117. $status = input('status', 1);//1获客 2拜访 3业绩 4回款 5工单
  118. $model = new AchievementModel();
  119. $achievement = $model->where([
  120. 'obj_id' => $staff_id,
  121. 'type' => 3,
  122. 'year' => $year,
  123. 'status' => $status
  124. ])->find();
  125. $achievement = $achievement ?? [];
  126. if ($achievement) {
  127. $achievement = $achievement->toArray();
  128. }
  129. $where = [];
  130. $startDate = date('Y-1-1');
  131. $endDate = date('Y-m-t');
  132. if ($status == 1) {//客户
  133. $where['createtime'] = ['between', [strtotime($startDate), strtotime($endDate) + 86400 - 1]];
  134. $where['create_staff_id'] = $staff_id;
  135. $moneys = Customer::where($where)
  136. ->field('count(*) as number,FROM_UNIXTIME(createtime,"%Y-%m") as month')
  137. ->group('month')->select();
  138. } elseif ($status == 2) {//拜访
  139. $where['actual_end_time'] = ['between', [strtotime($startDate), strtotime($endDate) + 86400 - 1]];
  140. $where['staff_id'] = $staff_id;
  141. $where['type'] = 3;
  142. $where['status'] = 2;
  143. $moneys = Event::where($where)->field('count(*) as number,FROM_UNIXTIME(actual_end_time,"%Y-%m") as month')
  144. ->group('month')->select();
  145. } elseif ($status == 3) {//合同
  146. $where['order_date'] = ['between', [$startDate, $endDate]];
  147. $where['check_status'] = 2;
  148. $where['owner_staff_id'] = $staff_id;
  149. $moneys = Contract::where($where)->group('month')
  150. ->field('sum(money) as number,`FROM_UNIXTIME(UNIX_TIMESTAMP(order_date),"%Y-%m") `as month')
  151. ->select();
  152. } elseif ($status == 4) {//回款
  153. $where['return_time'] = ['between', [$startDate, $endDate]];
  154. $where['check_status'] = 2;
  155. $where['owner_staff_id'] = $staff_id;
  156. $moneys = Receivables::where($where)->group('month')
  157. ->field('sum(money) as number,FROM_UNIXTIME(UNIX_TIMESTAMP(return_time),"%Y-%m") as month')
  158. ->select();
  159. } elseif ($status == 5) {
  160. $where['createtime'] = ['between', [strtotime($startDate), strtotime($endDate) + 86400 - 1]];
  161. $where['status'] = 3;
  162. $where['owner_staff_id'] = $staff_id;
  163. $moneys = Workorder::where($where)->group('month')
  164. ->field('count(*) as number,FROM_UNIXTIME(createtime,"%Y-%m") as month')
  165. ->select();
  166. }
  167. $moneys_list = [];
  168. foreach ($moneys as $v) {
  169. $moneys_list[$v['month']] = $v;
  170. }
  171. $total = ['money' => 0];
  172. foreach ($achievement as $k => $v) {
  173. if ($month = AchievementModel::getFieldMonth($k)) {
  174. $month = $year . '-' . $month;
  175. $achievement[$month] = isset($moneys_list[$month]) ? $moneys_list[$month]['number'] : 0;
  176. $total['money'] += $achievement[$month];
  177. }
  178. }
  179. //合计目标
  180. $total['achievement'] = isset($achievement['january']) ? ($achievement['january'] + $achievement['february'] + $achievement['march'] + $achievement['april'] + $achievement['may'] + $achievement['june'] + $achievement['july'] + $achievement['august'] + $achievement['september'] + $achievement['october'] + $achievement['november'] + $achievement['december']) : 0;
  181. //目标
  182. $achievement['yeartarget'] = $achievement['yeartarget'] ?? 0;
  183. $achievement['total_money'] = $total['money'];
  184. $achievement['surplus_money'] = $achievement['yeartarget'] - $achievement['total_money'];
  185. $achievement['total_achievement'] = $total['achievement'];
  186. $this->success('请求成功', $achievement);
  187. }
  188. //获取公司业绩目标
  189. public function getCompanyAchievement()
  190. {
  191. $year = input('year', date('Y'), 'intval');
  192. $status = input('status', 1);//1获客 2拜访 3业绩 4回款 5工单
  193. $model = new AchievementModel();
  194. $achievement = $model->where([
  195. 'type' => 1,
  196. 'year' => $year,
  197. 'status' => $status
  198. ])->find();
  199. if (empty($achievement)) {
  200. $model->save(['type' => 1, 'year' => $year, 'status' => $status]);
  201. $achievement = $model->where(['type' => 1, 'year' => $year, 'status' => $status])->find();
  202. }
  203. $achievement = $achievement->toArray();
  204. $where = [
  205. ];
  206. $startDate = date('Y-1-1');
  207. $endDate = date('Y-m-t');
  208. if ($status == 1) {//客户
  209. $where['createtime'] = ['between', [strtotime($startDate), strtotime($endDate) + 86400 - 1]];
  210. $moneys = Customer::where($where)
  211. ->field('count(*) as number,FROM_UNIXTIME(createtime,"%Y-%m") as month')
  212. ->group('month')->select();
  213. } elseif ($status == 2) {//拜访
  214. $where['actual_end_time'] = ['between', [strtotime($startDate), strtotime($endDate) + 86400 - 1]];
  215. $where['type'] = 3;
  216. $where['status'] = 2;
  217. $moneys = Event::where($where)->field('count(*) as number,FROM_UNIXTIME(actual_end_time,"%Y-%m") as month')
  218. ->group('month')->select();
  219. } elseif ($status == 3) {//合同
  220. $where['order_date'] = ['between', [$startDate, $endDate]];
  221. $where['check_status'] = 2;
  222. $moneys = Contract::where($where)->group('month')
  223. ->field('sum(money) as number,FROM_UNIXTIME(UNIX_TIMESTAMP(order_date),"%Y-%m") as month')
  224. ->select();
  225. } elseif ($status == 4) {//回款
  226. $where['return_time'] = ['between', [$startDate, $endDate]];
  227. $where['check_status'] = 2;
  228. $moneys = Receivables::where($where)->group('month')
  229. ->field('sum(money) as number,FROM_UNIXTIME(UNIX_TIMESTAMP(return_time),"%Y-%m") as month')
  230. ->select();
  231. }
  232. $moneys_list = [];
  233. foreach ($moneys as $v) {
  234. $moneys_list[$v['month']] = $v;
  235. }
  236. $total = ['money' => 0];
  237. foreach ($achievement as $k => $v) {
  238. if ($month = AchievementModel::getFieldMonth($k)) {
  239. $month = $year . '-' . $month;
  240. $achievement[$month] = isset($moneys_list[$month]) ? $moneys_list[$month]['number'] : 0;
  241. $total['money'] += $achievement[$month];
  242. }
  243. }
  244. //合计目标
  245. $total['achievement'] = isset($achievement['january']) ? ($achievement['january'] + $achievement['february'] + $achievement['march'] + $achievement['april'] + $achievement['may'] + $achievement['june'] + $achievement['july'] + $achievement['august'] + $achievement['september'] + $achievement['october'] + $achievement['november'] + $achievement['december']) : 0;
  246. //目标
  247. $achievement['yeartarget'] = $achievement['yeartarget'] ?? 0;
  248. $achievement['total_money'] = $total['money'];//合计业绩
  249. $achievement['surplus_money'] = $achievement['yeartarget'] - $achievement['total_money'];//剩余目标
  250. $achievement['total_achievement'] = $total['achievement'];//合计目标
  251. $this->success('请求成功', $achievement);
  252. }
  253. //修改目标
  254. public function addAchievement()
  255. {
  256. $type = input('type');//3个人 2团队 1公司
  257. $year = input('year', date('Y'), 'intval');
  258. $status = input('status', 1);//1获客 2拜访 3业绩 4回款
  259. $yeartarget = input('yeartarget');
  260. $ids = input('ids', 0);
  261. if ($type == 1) {
  262. $ids = 0;
  263. }
  264. $model = new AchievementModel();
  265. $ids = explode(',', $ids);
  266. $average = $yeartarget ? round($yeartarget / 12, 2) : 0;
  267. $save = [
  268. 'yeartarget' => $yeartarget ?? 0,
  269. 'january' => $average,
  270. 'february' => $average,
  271. 'march' => $average,
  272. 'april' => $average,
  273. 'may' => $average,
  274. 'june' => $average,
  275. 'july' => $average,
  276. 'august' => $average,
  277. 'september' => $average,
  278. 'october' => $average,
  279. 'november' => $average,
  280. 'december' => $average,
  281. ];
  282. Db::startTrans();
  283. try {
  284. foreach ($ids as $id) {
  285. $row = $model->where(['type' => $type, 'year' => $year, 'obj_id' => $id, 'status' => $status])->find();
  286. if (empty($row)) {
  287. $save['type'] = $type;
  288. $save['year'] = $year;
  289. $save['status'] = $status;
  290. $save['obj_id'] = $id;
  291. $save['createtime'] = time();
  292. $save['updatetime'] = time();
  293. $model->insert($save);
  294. } else {
  295. $model = new AchievementModel();
  296. $model->save($save, ['id' => $row['id']]);
  297. }
  298. }
  299. Db::commit();
  300. } catch (Exception $e) {
  301. Db::rollback();
  302. $this->error($e->getMessage());
  303. }
  304. $this->success('修改成功');
  305. }
  306. //员工 获取我的业绩目标详情
  307. public function getMyAchievementDetail()
  308. {
  309. $year = input('year', date('Y'), 'intval');
  310. $status = input('status', 1);//1销售(目标)2回款(目标)
  311. $type = input('type', 3);//3员工 2团队
  312. $model = new AchievementModel();
  313. $achievement = $model->where([
  314. 'obj_id' => $this->auth->id,
  315. 'type' => $type,
  316. 'year' => $year,
  317. 'status' => $status
  318. ])->find();
  319. $achievement = $achievement ?? [];
  320. if ($achievement) {
  321. $achievement = $achievement->toArray();
  322. }
  323. $achievement['yeartarget'] = $achievement['yeartarget'] ?? 0;
  324. $this->success('请求成功', $achievement);
  325. }
  326. //员工自己修改目标
  327. public function staffEditAchievement()
  328. {
  329. $type = input('type', 3);//3员工 2团队
  330. $year = input('year', date('Y'), 'intval');
  331. $status = input('status', 1);//1销售(目标)2回款(目标) 3 获客 4拜访
  332. $achievements = input('achievements/a');
  333. $flow_staff_ids = input('flow_staff_ids');
  334. $model = new AchievementRecords();
  335. $id = $this->auth->id;
  336. $update = [];
  337. if (isset($achievements['yeartarget'])) {
  338. $update['yeartarget'] = $achievements['yeartarget'] ?? 0;
  339. }
  340. $params = [
  341. 'type' => $type,
  342. 'year' => $year,
  343. 'status' => $status,
  344. 'obj_id' => $id,
  345. 'yeartarget' => $update['yeartarget'],
  346. 'january' => $achievements['january'] ?? 0,
  347. 'february' => $achievements['february'] ?? 0,
  348. 'march' => $achievements['march'] ?? 0,
  349. 'april' => $achievements['april'] ?? 0,
  350. 'june' => $achievements['june'] ?? 0,
  351. 'may' => $achievements['may'] ?? 0,
  352. 'july' => $achievements['july'] ?? 0,
  353. 'august' => $achievements['august'] ?? 0,
  354. 'september' => $achievements['september'] ?? 0,
  355. 'october' => $achievements['october'] ?? 0,
  356. 'november' => $achievements['november'] ?? 0,
  357. 'december' => $achievements['december'] ?? 0,
  358. 'flow_staff_ids' => $flow_staff_ids,
  359. 'check_status' => 0,
  360. 'owner_staff_id' => $id,
  361. 'createtime' => time(),
  362. 'updatetime' => time()
  363. ];
  364. Db::startTrans();
  365. try {
  366. $flow = Flow::getsteplist(Flow::ACHIEVEMENT_STATUS);
  367. $params['flow_id'] = $flow['flow_id'];
  368. $params['order_id'] = $flow['order_id'];
  369. if ($flow['status'] == 0) {//发起人自选
  370. if (empty($params['flow_staff_ids'])) {
  371. throw new Exception('审批人必须选择');
  372. }
  373. $params['flow_staff_ids'] = trim($params['flow_staff_ids']);
  374. } else {
  375. if (empty($flow['flow_staff_ids'])) {
  376. throw new Exception('没有直属上级无法审批,请联系管理员!');
  377. }
  378. $params['flow_staff_ids'] = trim($flow['flow_staff_ids']);
  379. }
  380. if ($model->insert($params) === false) {
  381. throw new Exception('添加失败');
  382. }
  383. $lastId = $model->getLastInsID();
  384. if ($flow['status'] == 1) {//固定审批
  385. //发送审批通知
  386. Flow::sendStepRecord($flow,Flow::ACHIEVEMENT_STATUS, $lastId);
  387. } else {//发起人自选 依次审批
  388. $staff_id = explode(',', $params['flow_staff_ids'])[0];
  389. if ($staff_id) {
  390. ExamineRecord::addExaminse(ExamineRecord::ACHIEVEMENT_TYPE, $lastId, $staff_id);
  391. }
  392. }
  393. Db::commit();;
  394. } catch (Exception $e) {
  395. Db::rollback();
  396. $this->error($e->getMessage());
  397. }
  398. $this->success('修改成功,请等待审批人审核!');
  399. }
  400. //业绩修改历史表
  401. public function editRecords()
  402. {
  403. $department_id = input('department_id');
  404. $year = input('year', date('Y'), 'intval');
  405. $status = input('status', 1);//1销售(目标)2回款(目标) 3 获客 4拜访
  406. $limit = input("limit/d", 10);
  407. $staff_id = input('staff_id', $this->auth->id);
  408. $type = input('type', 3);//3员工 2团队
  409. $where = [];
  410. if ($department_id) {
  411. $where['department_id'] = $department_id;
  412. }
  413. $where['year'] = $year;
  414. $where['status'] = $status;
  415. $model = new AchievementRecords();
  416. $list = $model->where([
  417. 'type' => $type,
  418. 'obj_id' => $staff_id
  419. ])->where($where)->with(['staff'])->order('id desc')->paginate($limit);
  420. $this->success('请求成功', $list);
  421. }
  422. //获取修改业绩详情表
  423. public function getRecordsDetail()
  424. {
  425. $id = input('id');
  426. $model = new AchievementRecords();
  427. $records = $model->where([])->where([
  428. 'id' => $id
  429. ])->with(['staff'])->find();
  430. if (empty($records)) {
  431. $this->error('记录不存在');
  432. }
  433. if ($records['check_status'] == 0 || $records['check_status'] == 1) {
  434. $records['is_examine'] = ExamineRecord::isExaminse(ExamineRecord::ACHIEVEMENT_TYPE, $id);
  435. } else {
  436. $records['is_examine'] = 0;
  437. }
  438. //标记通知已读
  439. Message::setRead(Message::ACHIEVEMENT_TYPE, $id, $this->auth->id);
  440. $this->success('请求成功', $records);
  441. }
  442. }