Workorder.php 58 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594
  1. <?php
  2. namespace addons\qingdongams\model;
  3. use think\Db;
  4. use think\Exception;
  5. use think\Model;
  6. use traits\model\SoftDelete;
  7. /**
  8. *工单表
  9. */
  10. class Workorder extends Model
  11. {
  12. use SoftDelete;
  13. protected $name = 'qingdongams_workorder';
  14. // 开启自动写入时间戳字段
  15. protected $autoWriteTimestamp = 'int';
  16. // 定义时间戳字段名
  17. protected $createTime = 'createtime';
  18. protected $updateTime = 'updatetime';
  19. protected $deleteTime = 'deletetime';
  20. // 追加属性
  21. protected $append = [
  22. 'show_staff_data',
  23. ];
  24. public function getCreatetimeAttr($value)
  25. {
  26. return date('Y-m-d H:i', $value);
  27. }
  28. public function getPayTimeAttr($value)
  29. {
  30. return $value ? date('Y-m-d H:i', $value) : '';
  31. }
  32. public function getAccepttimeAttr($value)
  33. {
  34. if (empty($value)) {
  35. return $value;
  36. }
  37. return date('Y-m-d H:i', $value);
  38. }
  39. public function getTrainContentAttr($value)
  40. {
  41. if (empty($value)) {
  42. return [];
  43. }
  44. $value=json_decode($value, true);
  45. if(empty($value)){
  46. return [];
  47. }
  48. foreach ($value as $k=>$v){
  49. if(empty($v['content'])){
  50. // continue;
  51. }
  52. foreach ($v['content'] as $kc=>$vc){
  53. if(empty($vc['autograph_url'])){
  54. continue;
  55. }
  56. $autograph_url=explode(',',$vc['autograph_url']);
  57. $autograph=[];
  58. foreach ($autograph_url as $url){
  59. $autograph[]= ['id'=>$vc['autograph_url'],'url'=>cdnurl(File::getUrl($url),true)];
  60. }
  61. $vc['autograph']=$autograph;
  62. $v['content'][$kc]=$vc;
  63. }
  64. $value[$k]=$v;
  65. }
  66. return $value;
  67. }
  68. //
  69. public function getPayServiceAttr($value)
  70. {
  71. if (empty($value)) {
  72. return [];
  73. }
  74. return json_decode($value, true);
  75. }
  76. //预计完成时间 expected_end_time
  77. public function getExpectedEndTimeAttr($value)
  78. {
  79. if (empty($value)) {
  80. return $value;
  81. }
  82. return date('Y-m-d H:i', $value);
  83. }
  84. public function getStarttimeAttr($value)
  85. {
  86. if (empty($value)) {
  87. return $value;
  88. }
  89. return date('Y-m-d H:i', $value);
  90. }
  91. public function getEndtimeAttr($value)
  92. {
  93. if (empty($value)) {
  94. return $value;
  95. }
  96. return date('Y-m-d H:i', $value);
  97. }
  98. public function getProductPartAttr($value)
  99. {
  100. $value = json_decode($value, true);
  101. if (empty($value)) {
  102. return [];
  103. }
  104. $data = [];
  105. foreach ($value as $v) {
  106. $cp = CustomerProduct::where(['id' => ['in', $v['customer_product_id']]])->with(['product'])->find();
  107. if(empty($cp)){
  108. continue;
  109. }
  110. $parts_id = explode(',', $v['parts_id']??'');
  111. if($cp['product_id']){
  112. $parts = Parts::where('', 'exp', Db::raw('FIND_IN_SET(' . $cp['product_id'] . ',product_id)'))->select();
  113. $parts = collection($parts)->toArray();
  114. }else{
  115. $parts=[];
  116. }
  117. foreach ($parts as $k => $p) {
  118. $p['is_select'] = in_array($p['id'], $parts_id) ? 1 : 0;
  119. $parts[$k] = $p;
  120. }
  121. $cp['parts'] = $parts;
  122. $data[] = $cp;
  123. }
  124. return $data;
  125. }
  126. public function getShowStaffDataAttr($value, $data)
  127. {
  128. if (!isset($data['show_staff_id'])) {
  129. return '';
  130. }
  131. $ids = explode(',', $data['show_staff_id']);
  132. return Staff::where(['id' => ['in', $ids]])->field('id,name,img,post,mobile')->select();
  133. }
  134. public function getPartsAttr($value)
  135. {
  136. if (empty($value)) {
  137. return [];
  138. }
  139. $value = json_decode($value, true);
  140. $data = [];
  141. foreach ($value as $v) {
  142. $p = Parts::where(['id' => $v['id']])->field('id,name,num,img,unit,price')->find();
  143. $p['number'] = isset($v['number']) ? $v['number'] : $v['num'];
  144. $data[] = $p;
  145. }
  146. return $data;
  147. }
  148. //已使用零件
  149. public function getUsePartsAttr($value)
  150. {
  151. if (empty($value)) {
  152. return [];
  153. }
  154. $value = json_decode($value, true);
  155. $data = [];
  156. foreach ($value as $v) {
  157. $p = Parts::where(['id' => $v['id']])->field('id,name,num,img,unit,price')->find();
  158. $p['number'] = isset($v['number']) ? $v['number'] : $v['num'];
  159. $p['is_charge'] = $v['is_charge'] ?? 1;
  160. $data[] = $p;
  161. }
  162. return $data;
  163. }
  164. //剩余零件
  165. public function getSurplusPartsAttr($value)
  166. {
  167. if (empty($value)) {
  168. return $value;
  169. }
  170. $value = json_decode($value, true);
  171. $data = [];
  172. foreach ($value as $v) {
  173. $p = Parts::where(['id' => $v['id']])->field('id,name,num,img,unit,price')->find();
  174. $p['number'] = isset($v['number']) ? $v['number'] : $v['num'];
  175. $data[] = $p;
  176. }
  177. return $data;
  178. }
  179. //获取评价附件
  180. public function getCommentFilesAttr($value)
  181. {
  182. $files = explode(',', $value);
  183. $result = [];
  184. foreach ($files as $fid) {
  185. if ($fid) {
  186. $result[] = cdnurl(File::getUrl($fid), true);
  187. }
  188. }
  189. return $result;
  190. }
  191. //回执附件 receipt_file_ids
  192. public function getReceiptFileIdsAttr($value)
  193. {
  194. if(empty($value)){
  195. return $value;
  196. }
  197. $files = explode(',', $value);
  198. $result = [];
  199. foreach ($files as $fid) {
  200. if ($fid) {
  201. $result[] = cdnurl(File::getUrl($fid), true);
  202. }
  203. }
  204. return $result;
  205. }
  206. public function getProductAttr($value)
  207. {
  208. if (empty($value)) {
  209. return '';
  210. }
  211. $value = json_decode($value, true);
  212. if (empty($value)) {
  213. return '';
  214. }
  215. $data = [];
  216. foreach ($value as $v) {
  217. if(!isset($v['product_id'])){
  218. continue;
  219. }
  220. $p = Product::where(['id' => $v['product_id']])->field('id,name,num,img,type_id')->find();
  221. $p['product_id'] = $p['id'] ?? 0;
  222. $p['number'] = $v['number'] ?? 0;
  223. $p['end_date'] = $v['end_date'] ?? '';
  224. $p['desc'] = $v['desc'] ?? '';
  225. $data[] = $p;
  226. }
  227. return $data;
  228. }
  229. //获取回款图片
  230. public function getCollectionImgAttr($value)
  231. {
  232. $files = explode(',', $value);
  233. $result = [];
  234. foreach ($files as $fid) {
  235. if ($fid) {
  236. $result[] = ['id' => $fid, 'url' => cdnurl(File::getUrl($fid), true)];
  237. }
  238. }
  239. return $result;
  240. }
  241. //获取评价附件
  242. public function getAutographUrlAttr($value)
  243. {
  244. if(empty($value)){
  245. return '';
  246. }
  247. return cdnurl(File::getUrl($value), true);
  248. }
  249. //获取支付附件
  250. public function getPayFilesAttr($value)
  251. {
  252. $files = explode(',', $value);
  253. $result = [];
  254. foreach ($files as $fid) {
  255. if ($fid) {
  256. $result[] = cdnurl(File::getUrl($fid), true);
  257. }
  258. }
  259. return $result;
  260. }
  261. //创建人 员工
  262. public function createStaff()
  263. {
  264. return $this->hasOne(Staff::class, 'id', 'create_staff_id')->field('id,name,img,post');
  265. }
  266. //创建人 联系人
  267. public function createPerson()
  268. {
  269. return $this->hasOne(Person::class, 'id', 'person_id')->field('id,account');
  270. }
  271. //获取联系人
  272. public function contacts()
  273. {
  274. return $this->hasOne(Contacts::class, 'id', 'contacts_id')
  275. ->order('is_major desc')->field('id,customer_id,name,mobile,mobilecode,region');
  276. }
  277. //获取售后服务用户端
  278. public function person()
  279. {
  280. return $this->hasOne(Person::class, 'id', 'person_id')->field('id,nickname,account');
  281. }
  282. //获取售后服务用户端
  283. public function comments()
  284. {
  285. return $this->hasOne(Comment::class, 'relation_id', 'id')->where(['relation_type' => 'workorder'])->field('id,relation_id,content,praise');
  286. }
  287. //获取客户
  288. public function customer()
  289. {
  290. return $this->hasOne(Customer::class, 'id', 'customer_id')->field('id,name,industry,level,source');
  291. }
  292. //获取评分情况
  293. public function visit()
  294. {
  295. return $this->hasOne(WorkorderVisit::class, 'workorder_id', 'id');
  296. }
  297. //获取日程
  298. public function getevent()
  299. {
  300. return $this->hasOne(Event::class, 'relation_id', 'id')->where(['relation_type' => 'workorder']);
  301. }
  302. //负责人
  303. public function ownerStaff()
  304. {
  305. return $this->hasOne(Staff::class, 'id', 'owner_staff_id')->field('id,name,img,mobile,email');
  306. }
  307. //获取附件记录
  308. public function file()
  309. {
  310. return $this->hasMany(WorkorderFile::class, 'workorder_id', 'id')->with('file')->field('workorder_id,file_id');
  311. }
  312. //创建工单
  313. public static function createWorkorder($params)
  314. {
  315. if (isset($params['file_ids'])) {
  316. $files = $params['file_ids'];
  317. unset($params['file_ids']);
  318. } else {
  319. $files = '';
  320. }
  321. //自定义字段
  322. $other = [];
  323. foreach ($params as $name => $val) {
  324. if (strstr($name, 'other_') !== false) {
  325. $other[$name] = $val;
  326. unset($params[$name]);
  327. continue;
  328. }
  329. if(empty($params[$name])){
  330. unset($params[$name]);
  331. continue;
  332. }
  333. }
  334. $staff = Staff::info();
  335. if (!empty($staff)) {
  336. $params['create_staff_id'] = $staff->id;
  337. }
  338. if (isset($params['start_time'])) {
  339. $params['start_time'] = strtotime($params['start_time']);
  340. }
  341. if (isset($params['end_time'])) {
  342. $params['end_time'] = strtotime($params['end_time']);
  343. }
  344. if (!isset($params['owner_staff_id']) || empty($params['owner_staff_id'])) {
  345. $params['owner_staff_id'] = $staff->id;
  346. }
  347. $parts = $params['parts'] ?? [];
  348. foreach ($parts as $pk => $pv) {
  349. $parts[$pk] = ['id' => $pv['id'], 'number' => $pv['number']];
  350. }
  351. $params['parts'] = json_encode($parts);
  352. $params['status'] = 1;
  353. if ($params['workorder_type'] == '返厂维修') {
  354. $params['process'] = 1;
  355. }
  356. if (isset($params['product']) && $params['product']) {
  357. //添加产品
  358. $product = $params['product'];
  359. if (is_array($product)){
  360. $params['product'] = json_encode($product);
  361. }
  362. if ($params['workorder_type'] == '产品发货') {
  363. $addAll = [];
  364. foreach ($product as $v) {
  365. for ($i = 0; $i < $v['number']; $i++) {
  366. $addAll[] = [
  367. 'customer_id' => $params['customer_id'],
  368. 'product_id' => $v['product_id'],
  369. 'pay_date' => date('Y-m-d'),
  370. 'create_staff_id' => $staff->id,
  371. 'createtime' => time(),
  372. ];
  373. }
  374. }
  375. $CustomerProductModel = new CustomerProduct();
  376. $customerProductIds = [];
  377. foreach ($addAll as $ins) {
  378. $CustomerProductModel->insert($ins);
  379. $customerProductIds[] = $CustomerProductModel->getLastInsID();
  380. }
  381. $params['customer_product_id'] = implode(',', $customerProductIds);
  382. }
  383. }
  384. $params['product_part'] = $params['product_part'] ?? [];
  385. if(is_array($params['product_part'])){
  386. $params['product_part'] = json_encode($params['product_part'] ?? []);
  387. }
  388. $workorderM = new self;
  389. // 调用当前模型对应的User验证器类进行数据验证
  390. $result = $workorderM->allowField(true)->save($params);
  391. $lastId = $workorderM->getLastInsID();
  392. if (false === $result) {
  393. // 验证失败 输出错误信息
  394. throw new Exception($workorderM->getError());
  395. }
  396. $otherModel = new WorkorderOther();
  397. if ($otherModel->save(['id' => $lastId, 'other' => json_encode($other, JSON_UNESCAPED_UNICODE)]) === false) {
  398. // 验证失败 输出错误信息
  399. throw new Exception($otherModel->getError());
  400. }
  401. if ($files) {
  402. WorkorderFile::addFiles($files, $lastId);
  403. }
  404. //操作记录
  405. OperationLog::createLog(OperationLog::WORKORDER_TYPE, $lastId, '创建工单');
  406. $content = '创建工单';
  407. $paramsSign['relation_type'] = StaffSignIn::WORKORDER_TYPE;
  408. $paramsSign['relation_id'] = $lastId;
  409. $paramsSign['files'] = $files ?? '';
  410. $paramsSign['relation_process'] = '创建工单';
  411. //创建跟进记录
  412. if(isset($params['customer_id']) && $params['customer_id']){
  413. StaffSignIn::quickSignIn($params['customer_id'], $content, $paramsSign);
  414. }
  415. return $lastId;
  416. }
  417. //创建工单
  418. public static function createCustomerWorkorder($params)
  419. {
  420. if (isset($params['file_ids'])) {
  421. $files = $params['file_ids'];
  422. unset($params['file_ids']);
  423. } else {
  424. $files = '';
  425. }
  426. //自定义字段
  427. $other = [];
  428. foreach ($params as $name => $val) {
  429. if (strstr($name, 'other_') !== false) {
  430. $other[$name] = $val;
  431. unset($params[$name]);
  432. }
  433. }
  434. if (isset($params['start_time'])) {
  435. $params['start_time'] = strtotime($params['start_time']);
  436. }
  437. if (isset($params['end_time'])) {
  438. $params['end_time'] = strtotime($params['end_time']);
  439. }
  440. $parts = $params['parts'] ?? [];
  441. foreach ($parts as $pk => $pv) {
  442. $parts[$pk] = ['id' => $pv['id'], 'number' => $pv['number']];
  443. }
  444. $params['parts'] = json_encode($parts);
  445. $params['status'] = 1;
  446. if($params['customer_product_id']){
  447. $customer_product_ids=explode(',',$params['customer_product_id']);
  448. $product_part=[];
  449. foreach ($customer_product_ids as $ids){
  450. $product_part[]=['customer_product_id'=>$ids,'parts_id'=>''];
  451. }
  452. $params['product_part'] =$product_part;
  453. }
  454. $params['product_part'] = json_encode($params['product_part'] ?? []);
  455. $params['create_staff_id']=1;
  456. $params['owner_staff_id']=1;
  457. $workorderM = new self;
  458. // 调用当前模型对应的User验证器类进行数据验证
  459. $result = $workorderM->allowField(true)->save($params);
  460. $lastId = $workorderM->getLastInsID();
  461. if (false === $result) {
  462. // 验证失败 输出错误信息
  463. throw new Exception($workorderM->getError());
  464. }
  465. $otherModel = new WorkorderOther();
  466. if ($otherModel->save(['id' => $lastId, 'other' => json_encode($other, JSON_UNESCAPED_UNICODE)]) === false) {
  467. // 验证失败 输出错误信息
  468. throw new Exception($otherModel->getError());
  469. }
  470. if ($files) {
  471. WorkorderFile::addFiles($files, $lastId);
  472. }
  473. //TODO
  474. $content = '客户提交了维修工单《' . $params['title'] . '》,请尽快处理!';
  475. // Message::batchMessage(Message::WORKORDER_TYPE, $lastId, $params['show_staff_id'],0, $content, 12);
  476. return $lastId;
  477. }
  478. //接受工单
  479. public static function acceptWorkorder($params)
  480. {
  481. $update = [
  482. 'status' => 2,
  483. 'process' => 0,
  484. 'accept_time' => time()
  485. ];
  486. if (isset($params['expected_end_time']) && $params['expected_end_time']) {
  487. $update['expected_end_time'] = strtotime($params['expected_end_time']);
  488. }
  489. if (self::where(['id' => $params['id'], 'status' => 1])->update($update) == false) {
  490. // 验证失败 输出错误信息
  491. throw new Exception('更新工单状态失败');
  492. }
  493. $staff = Staff::info();
  494. $row = self::get($params['id']);
  495. $content = '接受了工单';
  496. $params['relation_type'] = StaffSignIn::WORKORDER_TYPE;
  497. $params['relation_id'] = $row['id'];
  498. $params['relation_process'] = '接受工单';
  499. //创建跟进记录
  500. StaffSignIn::quickSignIn($row['customer_id'], $content, $params);
  501. return true;
  502. }
  503. //开始工单
  504. public static function startWorkorder($params)
  505. {
  506. $update = [
  507. 'process' => 1,
  508. 'start_time' => time(),
  509. ];
  510. if (isset($params['car_type']) && $params['car_type']) {
  511. $update['car_type'] = $params['car_type'];
  512. $update['car_number'] = $params['car_number'] ?? '';
  513. }
  514. if (isset($params['start_mileage']) && $params['start_mileage']) {
  515. $update['start_mileage'] = intval($params['start_mileage']);
  516. }
  517. if (self::where(['id' => $params['id'], 'status' => 2])->update($update) == false) {
  518. // 验证失败 输出错误信息
  519. throw new Exception('更新工单状态失败');
  520. }
  521. //日程开始
  522. Event::where(['relation_type' => 'workorder', 'relation_id' => $params['id']])
  523. ->update(['status' => 1]);
  524. $row = self::get($params['id']);
  525. $content = '开始了工单<br>备注:'.$params['desc']??'';
  526. $params['relation_type'] = StaffSignIn::WORKORDER_TYPE;
  527. $params['relation_id'] = $row['id'];
  528. $params['relation_process'] = '开始工单';
  529. //创建跟进记录
  530. StaffSignIn::quickSignIn($row['customer_id'], $content, $params);
  531. return true;
  532. }
  533. //录入零件
  534. public static function inputParts($params)
  535. {
  536. $parts = $params['parts'] ?? [];
  537. $update = [];
  538. if ($parts) {
  539. $data = [];
  540. foreach ($parts as $v) {
  541. $data[] = [
  542. 'id' => $v['id'],
  543. 'number' => $v['number']
  544. ];
  545. }
  546. $update['parts'] = json_encode($data);
  547. }
  548. if (self::where(['id' => $params['id']])->update($update) == false) {
  549. // 验证失败 输出错误信息
  550. throw new Exception('更新工单状态失败');
  551. }
  552. $row = self::get($params['id']);
  553. $content = '录入携带配件信息';
  554. $params['relation_type'] = StaffSignIn::WORKORDER_TYPE;
  555. $params['relation_id'] = $row['id'];
  556. $params['relation_process'] = '录入配件';
  557. //创建跟进记录
  558. StaffSignIn::quickSignIn($row['customer_id'], $content, $params);
  559. return true;
  560. }
  561. /**
  562. *修改工单信息
  563. */
  564. public static function updateWorkorder($params)
  565. {
  566. $row = self::get($params['id']);
  567. if (isset($params['file_ids'])) {
  568. $files = $params['file_ids'];
  569. unset($params['file_ids']);
  570. } else {
  571. $files = '';
  572. }
  573. if (isset($params['files'])) {
  574. $files = $params['files'];
  575. unset($params['files']);
  576. }
  577. //自定义字段
  578. $other = [];
  579. foreach ($params as $name => $val) {
  580. if (strstr($name, 'other_') !== false) {
  581. $other[$name] = $val;
  582. unset($params[$name]);
  583. }
  584. if(empty($val)){
  585. unset($params[$name]);
  586. }
  587. }
  588. if (isset($params['start_time'])) {
  589. $params['start_time'] = strtotime($params['start_time']);
  590. }
  591. if (isset($params['workorder_type'])) {
  592. unset($params['workorder_type']);
  593. }
  594. if (isset($params['end_time'])) {
  595. $params['end_time'] = strtotime($params['end_time']);
  596. }
  597. if (isset($params['product']) && $params['product']) {
  598. $product = $params['product'];
  599. if (is_array($product)){
  600. $params['product'] = json_encode($product);
  601. }
  602. if ($row->workorder_type == '产品发货') {
  603. $addAll = [];
  604. $staff = Staff::info();
  605. foreach ($product as $v) {
  606. for ($i = 0; $i < $v['number']; $i++) {
  607. $addAll[] = [
  608. 'customer_id' => $params['customer_id'],
  609. 'product_id' => $v['product_id'],
  610. 'pay_date' => date('Y-m-d'),
  611. 'create_staff_id' => $staff->id,
  612. 'createtime' => time(),
  613. ];
  614. }
  615. }
  616. $CustomerProductModel = new CustomerProduct();
  617. $customerProductIds = [];
  618. foreach ($addAll as $ins) {
  619. $CustomerProductModel->insert($ins);
  620. $customerProductIds[] = $CustomerProductModel->getLastInsID();
  621. }
  622. $CustomerProductModel
  623. ->where(['id' => ['in', explode(',', $row['customer_product_id'])]])->delete();
  624. $params['customer_product_id'] = implode(',', $customerProductIds);
  625. }
  626. }
  627. if(isset($params['appointment_time'])){
  628. $params['appointment_time']=$params['appointment_time']?:NULL;
  629. }
  630. $params['product_part'] = json_encode($params['product_part'] ?? []);
  631. if ($row->workorder_type == '返厂维修') {
  632. $params['process'] = 1;
  633. }
  634. $parts = $params['parts'] ?? [];
  635. foreach ($parts as $pk => $pv) {
  636. $parts[$pk] = ['id' => $pv['id'], 'number' => $pv['number']];
  637. }
  638. $params['parts'] = json_encode($parts);
  639. $customer = new self;
  640. // 调用当前模型对应的User验证器类进行数据验证
  641. $result = $customer->allowField(true)->isUpdate(true)->save($params, ['id' => $params['id']]);
  642. if (false === $result) {
  643. // 验证失败 输出错误信息
  644. throw new Exception($customer->getError());
  645. }
  646. //日程 修改信息
  647. if (isset($params['owner_staff_id'])) {
  648. $updateEvent = [
  649. 'title' => $params['title'],
  650. 'staff_id' => $params['owner_staff_id'],
  651. ];
  652. $eventModel = new Event();
  653. $eventModel->allowField(true)->save($updateEvent, ['relation_type' => 'workorder', 'relation_id' => $params['id']]);
  654. }
  655. $otherModel = new WorkorderOther();
  656. if ($otherModel->isUpdate(true)->save([
  657. 'id' => $params['id'],
  658. 'other' => json_encode($other, JSON_UNESCAPED_UNICODE)
  659. ]) === false) {
  660. // 验证失败 输出错误信息
  661. throw new Exception($otherModel->getError());
  662. }
  663. if ($files) {
  664. WorkorderFile::editFiles($files, $params['id']);
  665. }
  666. return true;
  667. }
  668. /**
  669. * 指派工单
  670. * @desc 备注
  671. * @update_date 2021/7/9 更新时间
  672. * @author zhangwei
  673. */
  674. public static function assignWorkorder($id, $staff_id, $desc)
  675. {
  676. $row = self::get($id);
  677. $update = [
  678. 'owner_staff_id' => $staff_id,
  679. 'status' => 1];
  680. if ($row['workorder_type'] == '返厂维修') {
  681. $update['process'] = 1;
  682. }
  683. $result = self::where(['id' => $id])->update($update);
  684. if (false === $result) {
  685. // 验证失败 输出错误信息
  686. throw new Exception('修改信息错误');
  687. }
  688. //日程 修改指派人
  689. Event::where(['relation_type' => 'workorder', 'relation_id' => $id])->update(['staff_id' => $staff_id]);
  690. $staff = Staff::info();
  691. $transferStaff = Staff::get($staff_id);
  692. $content = '将工单指派给[' . $transferStaff['name'] . ']' . '备注:' . $desc;
  693. $params['relation_type'] = StaffSignIn::WORKORDER_TYPE;
  694. $params['relation_id'] = $id;
  695. $params['relation_process'] = '指派工单';
  696. //创建跟进记录
  697. StaffSignIn::quickSignIn($row['customer_id'], $content, $params);
  698. //发送通知
  699. Message::addMessage(Message::WORKORDER_TYPE, $id, $row->owner_staff_id, $staff->id,
  700. "任务《{$row['title']}》已被指派给其他员工,请您及时审阅!");
  701. Message::addMessage(Message::WORKORDER_TYPE, $id, $staff_id, $staff->id,
  702. $staff->name . '指派给您一项任务,请您及时审阅');
  703. return true;
  704. }
  705. /**
  706. * 转派工单
  707. * @desc 备注
  708. * @update_date 2021/7/9 更新时间
  709. * @author zhangwei
  710. */
  711. public static function transferWorkorder($id, $staff_id, $desc='')
  712. {
  713. $workorder=self::get($id);
  714. $result = self::where(['id' => $id])
  715. ->update(['owner_staff_id' => $staff_id, 'status' => 1]);
  716. if (false === $result) {
  717. // 验证失败 输出错误信息
  718. throw new Exception('修改信息错误');
  719. }
  720. $staff = Staff::info();
  721. $transferStaff = Staff::get($staff_id);
  722. //日程 修改指派人
  723. Event::where(['relation_type' => 'workorder', 'relation_id' => $id])->update(['staff_id' => $staff_id]);
  724. $row = self::get($id);
  725. $content = '将工单转派给[' . $transferStaff['name'] . ']' . '原因:' . $desc;
  726. $params['relation_type'] = StaffSignIn::WORKORDER_TYPE;
  727. $params['relation_id'] = $id;
  728. $params['relation_process'] = '转派工单';
  729. //创建跟进记录
  730. StaffSignIn::quickSignIn($row['customer_id'], $content, $params);
  731. //发送通知
  732. Message::addMessage(Message::WORKORDER_TYPE, $id, $workorder->owner_staff_id, $staff->id,
  733. "任务《{$row['title']}》已被指派给其他员工,请您及时审阅!");
  734. Message::addMessage(Message::WORKORDER_TYPE, $id, $staff_id, $staff->id,
  735. $staff->name . '转派给您一项任务,请您及时审阅');
  736. return true;
  737. }
  738. /**
  739. * 工单签到
  740. * @desc
  741. * @update_date 2021/7/10 更新时间
  742. * @author zhangwei
  743. */
  744. public static function workorderSign($id, $desc, $params)
  745. {
  746. $workorder = self::get($id);
  747. $update = [
  748. 'process' => 2,//到达目标位置
  749. 'stock_up_time' => time(),
  750. ];
  751. if (isset($params['end_mileage']) && $params['end_mileage']) {
  752. $params['end_mileage']=intval($params['end_mileage']);
  753. if ($params['end_mileage'] <= $workorder['start_mileage']) {
  754. throw new Exception('结束公里数不能小于起始公里数');
  755. }
  756. //根据 起始公里数 ,录入行程费用
  757. $mileage = $params['end_mileage'] - $workorder['start_mileage'];
  758. $mileage_consume = [
  759. 'title' => $workorder['title'] . '-路程费用',
  760. 'number' => Consume::getNumber(),
  761. 'customer_id' => $workorder['customer_id'],
  762. 'relation_id' => $id,
  763. 'relation_type' => Consume::WORKORDER_TYPE,
  764. 'submit_date' => date('Y-m-d'),
  765. 'remark' => '',
  766. 'money' => Consume::getMileageMoney($mileage)
  767. ];
  768. $files = StaffSignIn::where(['relation_type' => StaffSignIn::WORKORDER_TYPE, 'relation_id' => $id])
  769. ->column('file_ids');
  770. $files[] = $params['file_ids'];
  771. $mileage_consume['detail'][] = [
  772. 'consume_date' => date('Y-m-d'),
  773. 'consume_type' => '交通费',
  774. 'consume_money' => Consume::getMileageMoney($mileage),
  775. 'mileage' => $mileage,
  776. 'car_type' => $workorder['car_type'],
  777. 'car_number' => $workorder['car_number'],
  778. 'start_mileage' => $workorder['start_mileage'],
  779. 'end_mileage' => $params['end_mileage'],
  780. 'file_ids' => implode(',', $files)
  781. ];
  782. Consume::createConsume($mileage_consume);
  783. $update['end_mileage'] = $params['end_mileage'];
  784. }
  785. $result = self::where(['id' => $id])->update($update);
  786. if (false === $result) {
  787. // 验证失败 输出错误信息
  788. throw new Exception('修改信息错误');
  789. }
  790. $row = self::get($id);
  791. $content = '已到达客户位置<br/>备注:'.$desc;
  792. $params['relation_type'] = StaffSignIn::WORKORDER_TYPE;
  793. $params['relation_id'] = $row['id'];
  794. $params['file_ids'] = $params['file_ids'] ?? '';
  795. $params['relation_process'] = '到达客户位置';
  796. //创建跟进记录
  797. StaffSignIn::quickSignIn($row['customer_id'], $content, $params);
  798. return true;
  799. }
  800. /**
  801. * 终止流程
  802. * @desc
  803. * @update_date 2021/7/10 更新时间
  804. * @author zhangwei
  805. */
  806. public static function cancelWorkorder($id, $desc)
  807. {
  808. $result = self::where(['id' => $id])->update([
  809. 'status' => 9,//取消工单
  810. ]);
  811. if (false === $result) {
  812. // 验证失败 输出错误信息
  813. throw new Exception('修改信息错误');
  814. }
  815. $staff = Staff::info();
  816. //日程 取消
  817. Event::where(['relation_type' => 'workorder', 'relation_id' => $id])->update(['status' => 3]);
  818. $row = self::get($id);
  819. $content = '终止流程,备注:' . $desc;
  820. $params['relation_type'] = StaffSignIn::WORKORDER_TYPE;
  821. $params['relation_id'] = $row['id'];
  822. $params['relation_process'] = '终止流程';
  823. //创建跟进记录
  824. StaffSignIn::quickSignIn($row['customer_id'], $content, $params);
  825. //发送通知
  826. Message::addMessage(Message::WORKORDER_TYPE, $id, $row->owner_staff_id, $staff->id,
  827. $staff->name . '终止任务《' . $row->title . '》,请您及时审阅');
  828. return true;
  829. }
  830. /**
  831. * 终止流程
  832. * @desc
  833. * @update_date 2021/7/10 更新时间
  834. * @author zhangwei
  835. */
  836. public static function failWorkorder($id, $desc)
  837. {
  838. $result = self::where(['id' => $id])->update([
  839. 'status' => 9,//取消工单
  840. ]);
  841. if (false === $result) {
  842. // 验证失败 输出错误信息
  843. throw new Exception('修改信息错误');
  844. }
  845. $staff = Staff::info();
  846. $workorder = self::get($id);
  847. //日程 取消
  848. Event::where(['relation_type' => 'workorder', 'relation_id' => $id])->update(['status' => 3]);
  849. $row = self::get($id);
  850. $content = $workorder['workorder_type'].'任务终止,备注:' . $desc;
  851. $params['relation_type'] = StaffSignIn::WORKORDER_TYPE;
  852. $params['relation_id'] = $row['id'];
  853. $params['relation_process'] = '任务终止';
  854. //创建跟进记录
  855. StaffSignIn::quickSignIn($row['customer_id'], $content, $params);
  856. //发送通知
  857. Message::addMessage(Message::WORKORDER_TYPE, $id, $row->owner_staff_id, $staff->id,
  858. $staff->name . '任务终止《' . $row->title . '》,请您及时审阅');
  859. return true;
  860. }
  861. //回访工单
  862. public static function visitWorkorder($params)
  863. {
  864. $result = self::where(['id' => $params['id']])->update([
  865. 'is_visit' => 1,//回访
  866. ]);
  867. if (false === $result) {
  868. // 验证失败 输出错误信息
  869. throw new Exception('修改信息错误');
  870. }
  871. $data = [
  872. 'workorder_id' => $params['id'],//
  873. 'satisfaction' => $params['satisfaction'],//
  874. 'visit_time' => $params['visit_time'],//回访时间
  875. 'visit_desc' => $params['visit_desc'],//回访意见
  876. 'visit_opinion' => $params['visit_opinion'],//
  877. 'visit_service' => $params['visit_service'],//
  878. 'visit_skill' => $params['visit_skill'],//
  879. 'skill_score' => $params['skill_score'],//
  880. 'service_score' => $params['service_score'],//
  881. 'opinion_score' => $params['opinion_score'],//
  882. ];
  883. $visit = new WorkorderVisit();
  884. $visit->save($data);
  885. $row = self::get($params['id']);
  886. $content = '回访工单';
  887. $params['relation_type'] = StaffSignIn::WORKORDER_TYPE;
  888. $params['relation_id'] = $row['id'];
  889. $params['relation_process'] = '回访工单';
  890. //创建跟进记录
  891. StaffSignIn::quickSignIn($row['customer_id'], $content, $params);
  892. return true;
  893. }
  894. //回执工单
  895. public static function receiptWorkorder($params)
  896. {
  897. $result = self::where(['id' => $params['id']])->update([
  898. 'receipt_file_ids' => $params['receipt_file_ids'],//回访
  899. 'receipt_date' => $params['receipt_date'],//回访
  900. ]);
  901. if (false === $result) {
  902. // 验证失败 输出错误信息
  903. throw new Exception('修改信息错误');
  904. }
  905. $row = self::get($params['id']);
  906. $content = '回执工单';
  907. $params['relation_type'] = StaffSignIn::WORKORDER_TYPE;
  908. $params['relation_id'] = $row['id'];
  909. $params['relation_process'] = '回执工单';
  910. $params['file_ids'] = $params['receipt_file_ids'];
  911. //创建跟进记录
  912. StaffSignIn::quickSignIn($row['customer_id'], $content, $params);
  913. return true;
  914. }
  915. /**
  916. * 撤销工单
  917. * @desc
  918. * @update_date 2021/7/10 更新时间
  919. * @author zhangwei
  920. */
  921. public static function revokeWorkorder($id, $desc)
  922. {
  923. $result = self::where(['id' => $id])->update([
  924. 'status' => 1,//取消工单
  925. 'process' => 0,
  926. ]);
  927. if (false === $result) {
  928. // 验证失败 输出错误信息
  929. throw new Exception('修改信息错误');
  930. }
  931. $staff = Staff::info();
  932. $row = self::get($id);
  933. $content = '撤销工单,备注:' . $desc;
  934. $params['relation_type'] = StaffSignIn::WORKORDER_TYPE;
  935. $params['relation_id'] = $row['id'];
  936. $params['relation_process'] = '撤销工单';
  937. //创建跟进记录
  938. StaffSignIn::quickSignIn($row['customer_id'], $content, $params);
  939. //发送通知
  940. Message::addMessage(Message::WORKORDER_TYPE, $id, $row->owner_staff_id, $staff->id,
  941. $staff->name . '撤销任务《' . $row->title . '》,请您及时审阅');
  942. return true;
  943. }
  944. /**
  945. * 签名去人
  946. * @desc
  947. * @update_date 2021/7/10 更新时间
  948. * @author zhangwei
  949. */
  950. public static function autograph($id, $url)
  951. {
  952. $result = self::where(['id' => $id])->update([
  953. 'is_autograph' => 1,//签名
  954. 'autograph_url' => $url,
  955. ]);
  956. if (false === $result) {
  957. // 验证失败 输出错误信息
  958. throw new Exception('修改信息错误');
  959. }
  960. $staff = Staff::info();
  961. $row = self::get($id);
  962. $content = '客户签字确认';
  963. $params['relation_type'] = StaffSignIn::WORKORDER_TYPE;
  964. $params['relation_id'] = $row['id'];
  965. $params['relation_process'] = '签字';
  966. $params['file_ids'] =$url;
  967. //创建跟进记录
  968. StaffSignIn::quickSignIn($row['customer_id'], $content, $params);
  969. return true;
  970. }
  971. /**
  972. * 完结工单
  973. * @desc 备注
  974. * @update_date 2021/7/10 更新时间
  975. * @author zhangwei
  976. */
  977. public static function completeWorkorder($id, $desc, $params)
  978. {
  979. $row = self::where(['id' => $id])->find();
  980. $update = [
  981. 'status' => 2,//进行中
  982. 'process' => 3,//录入零件 待录入费用
  983. 'train_content' => json_encode($params['train_content'] ?? [],JSON_UNESCAPED_UNICODE),
  984. 'end_time' => time()
  985. ];
  986. if($desc){
  987. $update['results']=$desc;
  988. }
  989. $use_parts = $params['use_parts'] ?? [];
  990. $pay_service = $params['pay_service'] ?? [];
  991. $new_use_parts = [];
  992. foreach ($use_parts as $v) {
  993. $new_use_parts[] = ['id' => $v['id'], 'number' => $v['number']];
  994. }
  995. $use_parts = $new_use_parts;
  996. if ($row['parts'] && $use_parts) {//计算剩余零件
  997. $parts=$row['parts'];
  998. $parts_key = [];
  999. foreach ($parts as $v) {
  1000. $parts_key[$v['id']] = $v['number'];
  1001. }
  1002. $use_parts_key = [];
  1003. foreach ($use_parts as $v) {
  1004. $use_parts_key[$v['id']] = $v['number'];
  1005. }
  1006. $surplus_parts = [];
  1007. foreach ($parts_key as $k => $number) {
  1008. if (isset($use_parts_key[$k])) {
  1009. $number = $number - $use_parts_key[$k];
  1010. $number = $number > 0 ? $number : 0;
  1011. }
  1012. $surplus_parts[] = ['id' => $k, 'number' => $number];
  1013. }
  1014. $update['surplus_parts'] = json_encode($surplus_parts);
  1015. }
  1016. !empty($use_parts) && $update['use_parts'] = json_encode($use_parts);
  1017. !empty($pay_service) && $update['pay_service'] = json_encode($pay_service);
  1018. $update['aftermarket_ids'] = $params['aftermarket_ids'] ?? '';//方案id
  1019. $update['aftermarket_text'] = $params['aftermarket_text'] ?? '';//其他方案
  1020. isset($params['resolved_results']) && $update['resolved_results'] = $params['resolved_results'];//
  1021. isset($params['complete_contact']) && $update['complete_contact'] = $params['complete_contact'];//
  1022. $update['complete_name'] = $params['complete_name'] ?? '';//
  1023. isset($params['mobile_result']) && $update['mobile_result'] = $params['mobile_result'];//电话结果 , 1 已解决 11 上门服务 12 返厂维修
  1024. isset($params['remarks']) && $update['remarks'] = $params['remarks'];//
  1025. isset($params['desc']) && $update['desc'] = $params['desc'];//
  1026. isset($params['is_mobile']) && $update['is_mobile'] = $params['is_mobile'];//
  1027. if (in_array($row['workorder_type'], ['上门安装', '返厂维修'])) {//
  1028. $update['process'] = 9;
  1029. $update['status'] = 3;//已完成
  1030. } elseif (in_array($row['workorder_type'], ['设计工单', '生产工单', '配件配送', '产品发货'])) {
  1031. $update['process'] = 9;
  1032. $update['status'] = 3;//已完成
  1033. } elseif ($row['workorder_type'] == '电话售后') {
  1034. if(empty($use_parts)){//不需要发送配件 直接完成
  1035. $update['process'] = 9;
  1036. $update['status'] = 3;//已完成
  1037. }
  1038. }
  1039. $result = self::where(['id' => $id])->update($update);
  1040. if (false === $result) {
  1041. // 验证失败 输出错误信息
  1042. throw new Exception('修改信息错误');
  1043. }
  1044. if ($row['workorder_type'] == '电话售后' && $use_parts) {
  1045. //自动发货审批人
  1046. $customerInfo = Customer::where(['id' => $row['customer_id']])->find();
  1047. $addWorkorder = [
  1048. 'workorder_number' => self::getWorkorderNumber(),
  1049. 'workorder_type' => '配件配送',
  1050. 'title' => '配件配送',
  1051. 'customer_id' => $customerInfo['id'],
  1052. 'contacts_id' => $row['contacts_id'],
  1053. 'address' => $customerInfo['address'],
  1054. 'address_detail' => $customerInfo['address_detail'],
  1055. 'lng' => $customerInfo['lng'],
  1056. 'lat' => $customerInfo['lat'],
  1057. 'priority' => '一般',
  1058. 'create_staff_id' => $row['owner_staff_id'],
  1059. 'owner_staff_id' => $row['owner_staff_id'],
  1060. 'parts' => $use_parts
  1061. ];
  1062. self::createWorkorder($addWorkorder);
  1063. }
  1064. $staff = Staff::info();
  1065. $row = self::get($id);
  1066. if ($row['workorder_type'] == '上门维修') {
  1067. $res = $row['resolved_results'];
  1068. $res = ($res == 1) ? '已解决' : (($res == 9) ? '未解决' : '返厂维修');
  1069. $content = '完成了工单;' . '<br>处理结果:' . $res;
  1070. } elseif ($row['workorder_type'] == '上门安装') {
  1071. $res = $row['resolved_results'];
  1072. if($res == 1){//安装成功
  1073. CustomerProduct::where(['id' => ['in', $row['customer_product_id']]])->update([
  1074. 'status' => 3
  1075. ]);
  1076. }
  1077. $res = ($res == 1) ? '安装成功' : (($res == 9) ? '安装失败' : '返厂维修');
  1078. $content = '完成了工单;' . '<br>处理结果:' . $res;
  1079. } else {
  1080. $content = '完成了工单;' . '<br>处理结果:' . $desc;
  1081. }
  1082. $params['relation_type'] = StaffSignIn::WORKORDER_TYPE;
  1083. $params['relation_id'] = $row['id'];
  1084. $params['file_ids'] = $params['file_ids'] ?? '';
  1085. $params['relation_process'] = '完成工单';
  1086. //创建跟进记录
  1087. StaffSignIn::quickSignIn($row['customer_id'], $content, $params);
  1088. //发送通知
  1089. Message::addMessage(Message::WORKORDER_TYPE, $id,$row->owner_staff_id,$staff->id,$staff->name . '《' . $row->title . '》任务已完成,请您继续操作');
  1090. //发送通知
  1091. if($update['status'] == 3){
  1092. self::setComplete($row['id']);
  1093. }
  1094. return true;
  1095. }
  1096. /**
  1097. * 填写维修结果
  1098. * @desc 备注
  1099. * @update_date 2021/7/10 更新时间
  1100. * @author zhangwei
  1101. */
  1102. public static function repairResult($id, $params)
  1103. {
  1104. $row = self::where(['id' => $id])->find();
  1105. $staff = Staff::info();
  1106. if ($params['resolved_results'] == 1) {//维修成功
  1107. $update = [
  1108. 'status' => 2,//处理中
  1109. 'process' => 3,//维修成功 待提交费用
  1110. 'resolved_results' => $params['resolved_results'] ?? 0,
  1111. 'is_replace' => $params['is_replace'] ?? 0,
  1112. 'is_recovery' => $params['is_recovery'] ?? 0,
  1113. 'maintain' => $params['maintain'] ?? '',
  1114. 'results' => $params['results'] ?? '',
  1115. 'start_time' => strtotime($params['start_time']),
  1116. 'end_time' => time()
  1117. ];
  1118. if ($row['is_over'] == 2) {//未过保
  1119. // $update['process']=5;
  1120. }
  1121. $use_parts = $params['use_parts'] ?? [];
  1122. $update['use_parts'] = [];
  1123. foreach ($use_parts as $k => $n) {
  1124. $update['use_parts'][] = ['id' => $n['id'], 'number' => $n['number'] ?? 0];
  1125. }
  1126. $update['use_parts'] = json_encode($update['use_parts']);
  1127. } else {//维修失败
  1128. $update = [
  1129. 'status' => 2,//处理中
  1130. 'process' => 2,
  1131. 'resolved_results' => $params['resolved_results'] ?? 0,
  1132. 'is_replace' => $params['is_replace'] ?? 0,
  1133. 'is_recovery' => $params['is_recovery'] ?? 0,
  1134. 'maintain' => $params['maintain'] ?? '',
  1135. 'results' => $params['results'] ?? '',
  1136. 'start_time' => strtotime($params['start_time']),
  1137. // 'owner_staff_id' => $row->create_staff_id
  1138. ];
  1139. $use_parts = $params['use_parts'] ?? [];
  1140. $update['use_parts'] = [];
  1141. foreach ($use_parts as $k => $n) {
  1142. $update['use_parts'][] = ['id' => $n['id'], 'number' => $n['number'] ?? 0];
  1143. }
  1144. $update['use_parts'] = json_encode($update['use_parts']);
  1145. }
  1146. $result = self::where(['id' => $id])->update($update);
  1147. if (false === $result) {
  1148. // 验证失败 输出错误信息
  1149. throw new Exception('修改信息错误');
  1150. }
  1151. //日程开始
  1152. Event::where(['relation_type' => 'workorder', 'relation_id' => $params['id']])
  1153. ->update(['status' => 1]);
  1154. $row = self::get($id);
  1155. if ($update['process'] == 2) {
  1156. $content = '填写维修结果<br>' . '处理结果:维修失败';
  1157. Message::addMessage(Message::WORKORDER_TYPE, $id, $row->owner_staff_id, $staff->id,
  1158. $staff->name . '的工单《' . $row->title . '》维修失败,请您及时处理');
  1159. } else {
  1160. $content = '填写维修结果<br>' . '处理结果:维修成功';
  1161. Message::addMessage(Message::WORKORDER_TYPE, $id, $row->owner_staff_id, $staff->id,
  1162. $staff->name . '的工单《' . $row->title . '》维修成功,请您录入相关费用!');
  1163. }
  1164. $params['relation_type'] = StaffSignIn::WORKORDER_TYPE;
  1165. $params['relation_id'] = $row['id'];
  1166. $params['file_ids'] = $params['file_ids'] ?? '';
  1167. $params['relation_process'] = '填写维修结果';
  1168. //创建跟进记录
  1169. StaffSignIn::quickSignIn($row['customer_id'], $content, $params);
  1170. return true;
  1171. }
  1172. /**
  1173. * 录入工单费用
  1174. */
  1175. public static function enterWorkorderMoney($id, $params)
  1176. {
  1177. $update = [
  1178. 'status' => 2,//处理中
  1179. 'process' => 7,//费用待审核
  1180. ];
  1181. $pay_service = $params['pay_service'] ?? [];
  1182. $update['pay_service'] = json_encode($pay_service);
  1183. $update['total_money'] = $params['total_money'] ?? 0;//总费用
  1184. $update['discount_money'] = $params['discount_money'] ?? 0;//优惠费用
  1185. $update['money'] = $params['total_money'] - $update['discount_money'];//当前价格
  1186. $update['tax'] = $params['tax'] ?? '';//当前价格
  1187. $update['collection_img'] = $params['collection_img'] ?? '';//
  1188. $update['collection_deposit'] = $params['collection_deposit'] ?? '';//
  1189. $update['collection_account'] = $params['collection_account'] ?? '';
  1190. $update['collection_name'] = $params['collection_name'] ?? '';//
  1191. $update['is_charge']=$params['is_charge']??1;//是否收费 1收费 2不收费
  1192. $update['use_parts'] = [];
  1193. $use_parts = $params['use_parts'] ?? [];
  1194. foreach ($use_parts as $k => $n) {
  1195. $update['use_parts'][] = [
  1196. 'id' => $n['id'],
  1197. 'number' => $n['number'] ?? 0,
  1198. 'is_charge' => $n['is_charge'] ?? 1,
  1199. ];
  1200. }
  1201. $update['use_parts'] = json_encode($update['use_parts']);
  1202. $flow = Flow::getsteplist(Flow::WORKORDER_STATUS);
  1203. $update['flow_id'] = $flow['flow_id'];
  1204. $update['order_id'] = $flow['order_id'];
  1205. if ($flow['status'] == 0) {//发起人自选
  1206. if (empty($params['flow_staff_ids'])) {
  1207. throw new Exception('审批人必须选择');
  1208. }
  1209. $update['flow_staff_ids'] = trim($params['flow_staff_ids']);
  1210. } else {
  1211. $update['flow_staff_ids'] = trim($flow['flow_staff_ids']);
  1212. }
  1213. $update['check_status'] = 1;
  1214. if ($flow['status'] == 1) {//固定审批
  1215. //发送审批通知
  1216. Flow::sendStepRecord($flow,Flow::WORKORDER_STATUS, $id);
  1217. } else {//发起人自选 依次审批
  1218. $staff_id = explode(',', $params['flow_staff_ids'])[0];
  1219. if ($staff_id) {
  1220. ExamineRecord::addExaminse(ExamineRecord::WORKORDER_TYPE, $id, $staff_id);
  1221. }
  1222. }
  1223. $result = self::where(['id' => $id])->update($update);
  1224. if (false === $result) {
  1225. // 验证失败 输出错误信息
  1226. throw new Exception('修改信息错误');
  1227. }
  1228. $row = self::get($id);
  1229. $content = '录入维修费用<br> 金额:' . $update['money'];
  1230. $params['relation_type'] = StaffSignIn::WORKORDER_TYPE;
  1231. $params['relation_id'] = $row['id'];
  1232. $params['file_ids'] = $params['file_ids'] ?? '';
  1233. $params['relation_process'] = '录入维修费用';
  1234. //创建跟进记录
  1235. StaffSignIn::quickSignIn($row['customer_id'], $content, $params);
  1236. return true;
  1237. }
  1238. //财务确认回款
  1239. public static function financialAudit($workorder_id)
  1240. {
  1241. $row = self::where(['id' => $workorder_id])->find();
  1242. //设置产品编号
  1243. self::where(['id' => $workorder_id])->update(['is_financial_audit' => 1]);
  1244. $content = '财务确认收款';
  1245. $data['relation_type'] = StaffSignIn::WORKORDER_TYPE;
  1246. $data['relation_id'] = $row['id'];
  1247. $data['relation_process'] = '确认收款';
  1248. //创建跟进记录
  1249. StaffSignIn::quickSignIn($row['customer_id'], $content, $data);
  1250. $staff=Staff::info();
  1251. Message::setRead(Message::WORKORDER_RECEIVABLES,$workorder_id,$staff->id);
  1252. return true;
  1253. }
  1254. //设置产品编号
  1255. public static function setProductNumber($workorder_id, $params)
  1256. {
  1257. $row = self::where(['id' => $workorder_id])->find();
  1258. $staff = Staff::info();
  1259. //设置产品编号
  1260. self::where(['id' => $workorder_id])->update(['process' => 2, 'stock_up_time' => time()]);
  1261. $content = '录入了产品编号';
  1262. $self = new self();
  1263. $self->allowField(true)->save($params, ['id' => $params['workorder_id']]);
  1264. $data['relation_type'] = StaffSignIn::WORKORDER_TYPE;
  1265. $data['relation_id'] = $row['id'];
  1266. $data['relation_process'] = '设置产品编号';
  1267. //创建跟进记录
  1268. StaffSignIn::quickSignIn($row['customer_id'], $content, $data);
  1269. return true;
  1270. }
  1271. //设置产品编号
  1272. public static function setPartsNumber($workorder_id, $params)
  1273. {
  1274. $row = self::where(['id' => $workorder_id])->find();
  1275. $staff = Staff::info();
  1276. //设置产品编号
  1277. self::where(['id' => $workorder_id])->update(['process' => 2, 'stock_up_time' => time()]);
  1278. $content = '提交配送信息成功';
  1279. $self = new self();
  1280. $self->allowField(true)->save($params, ['id' => $params['workorder_id']]);
  1281. $data['relation_type'] = StaffSignIn::WORKORDER_TYPE;
  1282. $data['relation_id'] = $row['id'];
  1283. $data['relation_process'] = '提交配送信息';
  1284. //创建跟进记录
  1285. StaffSignIn::quickSignIn($row['customer_id'], $content, $data);
  1286. return true;
  1287. }
  1288. //添加物流信息 发货
  1289. public static function setLogistics($workorder_id, $product_ids)
  1290. {
  1291. $row = self::where(['id' => $workorder_id])->find();
  1292. $update = ['process' => 3];
  1293. if ($row['workorder_type'] == '产品发货') {//运输中
  1294. // $customer_product_id=$row['customer_product_id']??'';
  1295. // $customer_product_id=explode(',',$customer_product_id);
  1296. CustomerProduct::where(['id' => ['in', $product_ids]])->update([
  1297. 'status' => 1
  1298. ]);
  1299. } else if ($row['workorder_type'] == '返厂维修') {
  1300. $update['process'] = 8;//等待物流到货
  1301. }
  1302. self::where(['id' => $workorder_id])->update($update);
  1303. $content = '提交了物流信息';
  1304. $params['relation_type'] = StaffSignIn::WORKORDER_TYPE;
  1305. $params['relation_id'] = $workorder_id;
  1306. $params['relation_process'] = '添加物流信息';
  1307. //创建跟进记录
  1308. StaffSignIn::quickSignIn($row['customer_id'], $content, $params);
  1309. return true;
  1310. }
  1311. //添加品质异常单
  1312. public static function addProgress($params)
  1313. {
  1314. $staff=Staff::info();
  1315. //填写进度
  1316. $model = new WorkorderProgress();
  1317. $params['create_staff_id'] = $staff->id;
  1318. $model->save($params);
  1319. $workorderModel = new self();
  1320. $row = $workorderModel->get($params['workorder_id']);
  1321. $flow_staff_ids = explode(',', trim($row['flow_staff_ids'], ','));
  1322. $check_staff_ids = explode(',', trim($row['check_staff_ids'], ','));
  1323. $check_staff_ids[] = $staff->id;
  1324. $diff = array_diff($flow_staff_ids, $check_staff_ids);
  1325. $diff = array_values($diff);
  1326. if (empty($diff)) {
  1327. $workorderModel->save([
  1328. 'status' => 3,
  1329. 'check_status' => 2,
  1330. 'check_staff_ids' => implode(',', $check_staff_ids)
  1331. ], ['id' => $row->id]);
  1332. Message::addMessage(Message::WORKORDER_TYPE, $row->id, $row['create_staff_id'], $staff->id, $staff->name . '已经完成了品质异常单,请及时查看!');
  1333. } else {
  1334. //处理中
  1335. $workorderModel->save([
  1336. 'check_staff_ids' => implode(',', $check_staff_ids),
  1337. 'status' => 2,
  1338. 'owner_staff_id' => $diff[0],
  1339. ], ['id' => $row->id]);
  1340. Message::addMessage(Message::WORKORDER_TYPE, $row->id, $diff[0], $row['create_staff_id'], $staff->name . '提交了一个品质异常单需要您处理!');
  1341. }
  1342. $content = '提交异常分析结果';
  1343. $params['relation_type'] = StaffSignIn::WORKORDER_TYPE;
  1344. $params['relation_id'] = $params['workorder_id'];
  1345. $params['relation_process'] = '提交异常分析结果';
  1346. //创建跟进记录
  1347. StaffSignIn::quickSignIn($row['customer_id'], $content, $params);
  1348. return true;
  1349. }
  1350. //取消测试/继续测试
  1351. public static function continueTest($id, $is_continue)
  1352. {
  1353. $workorder = self::where(['id' => $id])->find();
  1354. if(empty($workorder)){
  1355. return false;
  1356. }
  1357. if ($is_continue == 1) {//继续维修
  1358. $data['process'] = 6;
  1359. $result = self::where(['id' => $id])->update($data);
  1360. if (false === $result) {
  1361. // 验证失败 输出错误信息
  1362. throw new Exception('修改信息错误');
  1363. }
  1364. Event::where(['relation_type' => 'workorder', 'relation_id' => $id, 'type' => 1])
  1365. ->update(['status' => 1]);
  1366. $content = '根据评估结果,继续维修';
  1367. $params['relation_type'] = StaffSignIn::WORKORDER_TYPE;
  1368. $params['relation_id'] = $id;
  1369. //创建跟进记录
  1370. StaffSignIn::quickSignIn($workorder['customer_id'], $content, $params);
  1371. $staff = Staff::info();
  1372. //发送通知
  1373. $messageContent = $staff->name . '《' . $workorder['title'] . '》评估继续维修,请您及时审阅';
  1374. $toStaff = [$workorder['create_staff_id'], $workorder['owner_staff_id']];
  1375. $toStaff = implode(',', $toStaff);
  1376. Message::addMessage(Message::WORKORDER_TYPE, $id, $workorder['owner_staff_id'], $staff->id, $messageContent);
  1377. } elseif ($is_continue == 9) {//取消维修
  1378. $data['process'] = 9;
  1379. $data['status'] = 3;
  1380. $result = self::where(['id' => $id])->update($data);
  1381. if (false === $result) {
  1382. // 验证失败 输出错误信息
  1383. throw new Exception('修改信息错误');
  1384. }
  1385. //取消任务
  1386. Event::where(['relation_type' => 'workorder', 'relation_id' => $id])->update([
  1387. 'status' => 3]);
  1388. $content = '销售根据评估结果,取消维修';
  1389. $params['relation_type'] = StaffSignIn::WORKORDER_TYPE;
  1390. $params['relation_id'] = $id;
  1391. //创建跟进记录
  1392. StaffSignIn::quickSignIn($workorder['customer_id'], $content, $params);
  1393. $staff = Staff::info();
  1394. $messageContent = $staff->name . '《' . $workorder['title'] . '》评估取消维修,请您及时审阅';
  1395. Message::addMessage(Message::WORKORDER_TYPE, $id, $workorder['owner_staff_id'], $staff->id, $messageContent);
  1396. }
  1397. return true;
  1398. }
  1399. public static function getWorkorderNumber()
  1400. {
  1401. return 'S' . date('ymd') . rand(100, 999);
  1402. }
  1403. //工单完成
  1404. public static function setComplete($workorder_id)
  1405. {
  1406. $staff=Staff::info();
  1407. $row=self::get($workorder_id);
  1408. //日程完成
  1409. Event::where(['relation_type' => 'workorder', 'relation_id' => $workorder_id])
  1410. ->update(['status' => 2]);
  1411. if (in_array($row['workorder_type'], self::getVisitType())) {
  1412. //回访客户通知
  1413. Message::addMessage(Message::WORKORDER_TYPE, $row['id'], $row['create_staff_id'], $staff->id, '《' . $row->title . '》工单已完成,请您尽快回访客户!');
  1414. }
  1415. if($row['is_pay'] == 1){
  1416. //发送通知
  1417. Message::addMessage(Message::WORKORDER_RECEIVABLES, $workorder_id,$row['create_staff_id'],$staff->id, '《' . $row->title . '》任务已完成,请您及时确认回款情况!');
  1418. }
  1419. return true;
  1420. }
  1421. //获取回访工单类型
  1422. public static function getVisitType()
  1423. {
  1424. return ['上门安装', '上门维修','配件安装'];
  1425. }
  1426. }