ReceivablesPlan.php 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | Description: 回款计划计划
  4. // +----------------------------------------------------------------------
  5. // | Author: Michael_xu | gengxiaoxu@5kcrm.com
  6. // +----------------------------------------------------------------------
  7. namespace app\crm\model;
  8. use app\admin\traits\FieldVerificationTrait;
  9. use think\Db;
  10. use app\admin\model\Common;
  11. use app\crm\model\Contract as ContractModel;
  12. use think\Request;
  13. use think\Validate;
  14. class ReceivablesPlan extends Common
  15. {
  16. use FieldVerificationTrait;
  17. /**
  18. * 为了数据库的整洁,同时又不影响Model和Controller的名称
  19. * 我们约定每个模块的数据表都加上相同的前缀,比如CRM模块用crm作为数据表前缀
  20. */
  21. protected $name = 'crm_receivables_plan';
  22. protected $createTime = 'create_time';
  23. protected $updateTime = 'update_time';
  24. protected $autoWriteTimestamp = true;
  25. /**
  26. * [getDataList 回款计划list]
  27. * @author Michael_xu
  28. * @param [string] $map [查询条件]
  29. * @param [number] $page [当前页数]
  30. * @param [number] $limit [每页数量]
  31. * @param [string] $types 1 未使用的回款计划
  32. * @return [array] [description]
  33. */
  34. public function getDataList($request)
  35. {
  36. $userModel = new \app\admin\model\User();
  37. $search = $request['search'];
  38. $user_id = $request['user_id'];
  39. $scene_id = (int)$request['scene_id'];
  40. $check_status = $request['check_status'];
  41. $types = $request['types'];
  42. $getCount = $request['getCount'];
  43. $status = isset($request['status']) ? $request['status'] : 1;
  44. $dealt = $request['dealt']; # 待办事项
  45. unset($request['scene_id']);
  46. unset($request['search']);
  47. unset($request['user_id']);
  48. unset($request['check_status']);
  49. unset($request['types']);
  50. unset($request['getCount']);
  51. unset($request['status']);
  52. unset($request['dealt']);
  53. $request = $this->fmtRequest( $request );
  54. $map = $request['map'] ? : [];
  55. if (isset($map['search'])) {
  56. //普通筛选
  57. $map['name'] = ['like', '%'.$map['search'].'%'];
  58. unset($map['search']);
  59. } else {
  60. // 高级筛选
  61. $map = advancedQuery($map, 'crm', 'receivables_plan', 'index');
  62. }
  63. if ($map['receivables_plan.owner_user_id']) {
  64. $map['contract.owner_user_id'] = $map['receivables_plan.owner_user_id'];
  65. unset($map['receivables_plan.owner_user_id']);
  66. }
  67. $whereData = [];
  68. if ($check_status) {
  69. unset($map['receivables_plan.check_status']);
  70. if ($check_status == 2) {
  71. $map['receivables.check_status'] = $check_status;
  72. } else {
  73. unset($map['receivables_plan.receivables_id']);
  74. $data = [];
  75. $data['check_status'] = $check_status;
  76. $whereData = function($query) use ($data){
  77. $query->where(['receivables_plan.receivables_id'=> ['eq',0]])
  78. ->whereOr(['receivables.check_status' => $data['check_status']]);
  79. };
  80. }
  81. }
  82. // @ymob 2019-12-11 17:51:54
  83. // 修改回款时,回款计划选项列表应该包含该回款对应的回款计划 不能过滤
  84. // 将types改为status,status:可用的回款计划 fanqi
  85. if (empty($dealt)) { # 不是待办事项
  86. if ($request['map']['receivables_id']) {
  87. if (!empty($request['map']['contract_id'])) {
  88. $map = "
  89. (`receivables_plan`.`contract_id` = {$request['map']['contract_id']} AND `receivables_plan`.`receivables_id` = {$request['map']['receivables_id']})
  90. OR
  91. (`receivables_plan`.`contract_id` = {$request['map']['contract_id']} AND `receivables_plan`.`receivables_id` = 0)
  92. ";
  93. } else {
  94. $map = " (`receivables_plan`.`receivables_id` = 0 )";
  95. }
  96. } elseif ($status == 0) {
  97. $map['receivables_plan.receivables_id'] = 0;
  98. }
  99. }
  100. $dataCount = db('crm_receivables_plan')
  101. ->alias('receivables_plan')
  102. ->join('__CRM_CONTRACT__ contract','receivables_plan.contract_id = contract.contract_id','LEFT')
  103. ->join('__CRM_CUSTOMER__ customer','receivables_plan.customer_id = customer.customer_id','LEFT')
  104. ->join('__CRM_RECEIVABLES__ receivables','receivables_plan.plan_id = receivables.plan_id','LEFT')
  105. ->where($map)
  106. ->where($whereData)
  107. ->count('receivables_plan.plan_id');
  108. if (!empty($getCount) && $getCount == 1) {
  109. $data['dataCount'] = !empty($dataCount) ? $dataCount : 0;
  110. return $data;
  111. }
  112. $list = db('crm_receivables_plan')
  113. ->alias('receivables_plan')
  114. ->join('__CRM_CONTRACT__ contract','receivables_plan.contract_id = contract.contract_id','LEFT')
  115. ->join('__CRM_CUSTOMER__ customer','receivables_plan.customer_id = customer.customer_id','LEFT')
  116. ->join('__CRM_RECEIVABLES__ receivables','receivables_plan.plan_id = receivables.plan_id','LEFT')
  117. ->limit($request['offset'], $request['length'])
  118. ->field('receivables_plan.*,customer.name as customer_name,contract.num as contract_name,receivables.receivables_id,receivables.check_status')
  119. ->where($map)
  120. ->where($whereData)
  121. ->select();
  122. foreach ($list as $k=>$v) {
  123. $list[$k]['create_user_id_info'] = $userModel->getUserById($v['create_user_id']);
  124. $list[$k]['contract_id_info']['name'] = $v['contract_name'] ? : '';
  125. $list[$k]['contract_id_info']['contract_id'] = $v['contract_id'] ? : '';
  126. $list[$k]['customer_id_info']['name'] = $v['customer_name'] ? : '';
  127. $list[$k]['customer_id_info']['customer_id'] = $v['customer_id'] ? : '';
  128. }
  129. $data = [];
  130. $data['list'] = $list;
  131. $data['dataCount'] = $dataCount ? : 0;
  132. return $data ? : [];
  133. }
  134. /**
  135. * 创建回款计划信息
  136. * @author Michael_xu
  137. * @param
  138. * @return
  139. */
  140. public function createData($param)
  141. {
  142. $userId = $param['user_id'];
  143. unset($param['user_id']);
  144. if (!$param['contract_id']) {
  145. $this->error = '请先选择合同';
  146. return false;
  147. } else {
  148. $res = ContractModel::where(['contract_id' => $param['contract_id']])->value('check_status');
  149. if (6 == $res) {
  150. $this->error = '合同已作废';
  151. return false;
  152. }
  153. if (!in_array($res,['2'])) {
  154. $this->error = '当前合同未审核通过,不能添加回款';
  155. return false;
  156. }
  157. }
  158. if ($param['remind'] > 90) {
  159. $this->error = '提前提醒最大时间为 90 天';
  160. return false;
  161. }
  162. // // 自动验证
  163. // $validate = validate($this->name);
  164. // if (!$validate->check($param)) {
  165. // $this->error = $validate->getError();
  166. // return false;
  167. // }
  168. // 数据验证
  169. $validateResult = $this->fieldDataValidate($param, 'crm_receivables_plan', $userId);
  170. if (!empty($validateResult)) {
  171. $this->error = $validateResult;
  172. return false;
  173. }
  174. if ($param['file_ids']) $param['file'] = arrayToString($param['file_ids']); //附件
  175. //期数规则(1,2,3..)
  176. $maxNum = db('crm_receivables_plan')->where(['contract_id' => $param['contract_id']])->max('num');
  177. $param['num'] = $maxNum ? $maxNum+1 : 1;
  178. //提醒日期
  179. $param['remind_date'] = $param['remind'] ? date('Y-m-d',strtotime($param['return_date'])-86400*$param['remind']) : $param['return_date'];
  180. $fieldModel = new \app\admin\model\Field();
  181. // 处理部门、员工、附件、多选类型字段
  182. $arrFieldAtt = $fieldModel->getArrayField('crm_receivables_plan');
  183. foreach ($arrFieldAtt AS $key => $value) {
  184. $param[$value] = !empty($param[$value]) ? arrayToString($param[$value]) : '';
  185. }
  186. // 处理日期(date)类型
  187. $dateField = $fieldModel->getFieldByFormType('crm_receivables_plan', 'date');
  188. foreach ($dateField AS $key => $value) {
  189. $param[$value] = !empty($param[$value]) ? $param[$value] : null;
  190. }
  191. // 处理手写签名类型
  192. $handwritingField = $fieldModel->getFieldByFormType('crm_receivables_plan', 'handwriting_sign');
  193. foreach ($handwritingField AS $key => $value) {
  194. $param[$value] = !empty($param[$value]['file_id']) ? $param[$value]['file_id'] : '';
  195. }
  196. // 处理地址、定位、日期区间、明细表格类型字段
  197. $receivablesPlanData = [];
  198. $positionField = $fieldModel->getFieldByFormType('crm_receivables_plan', 'position');
  199. $locationField = $fieldModel->getFieldByFormType('crm_receivables_plan', 'location');
  200. $dateIntervalField = $fieldModel->getFieldByFormType('crm_receivables_plan', 'date_interval');
  201. $detailTableField = $fieldModel->getFieldByFormType('crm_receivables_plan', 'detail_table');
  202. foreach ($param AS $key => $value) {
  203. // 处理地址类型字段数据
  204. if (in_array($key, $positionField)) {
  205. if (!empty($value)) {
  206. $receivablesPlanData[] = [
  207. 'field' => $key,
  208. 'content' => json_encode($value, JSON_NUMERIC_CHECK),
  209. 'create_time' => time()
  210. ];
  211. $positionNames = array_column($value, 'name');
  212. $param[$key] = implode(',', $positionNames);
  213. } else {
  214. $param[$key] = '';
  215. }
  216. }
  217. // 处理定位类型字段数据
  218. if (in_array($key, $locationField)) {
  219. if (!empty($value)) {
  220. $receivablesPlanData[] = [
  221. 'field' => $key,
  222. 'content' => json_encode($value, JSON_NUMERIC_CHECK),
  223. 'create_time' => time()
  224. ];
  225. $param[$key] = $value['address'];
  226. } else {
  227. $param[$key] = '';
  228. }
  229. }
  230. // 处理日期区间类型字段数据
  231. if (in_array($key, $dateIntervalField)) {
  232. if (!empty($value)) {
  233. $receivablesPlanData[] = [
  234. 'field' => $key,
  235. 'content' => json_encode($value, JSON_NUMERIC_CHECK),
  236. 'create_time' => time()
  237. ];
  238. $param[$key] = implode('_', $value);
  239. } else {
  240. $param[$key] = '';
  241. }
  242. }
  243. // 处理明细表格类型字段数据
  244. if (in_array($key, $detailTableField)) {
  245. if (!empty($value)) {
  246. $receivablesPlanData[] = [
  247. 'field' => $key,
  248. 'content' => json_encode($value, JSON_NUMERIC_CHECK),
  249. 'create_time' => time()
  250. ];
  251. $param[$key] = $key;
  252. } else {
  253. $param[$key] = '';
  254. }
  255. }
  256. }
  257. if ($this->data($param)->allowField(true)->save()) {
  258. $data = [];
  259. $data['plan_id'] = $this->plan_id;
  260. // 添加回款计划扩展数据
  261. array_walk($receivablesPlanData, function (&$val) use ($data) {
  262. $val['plan_id'] = $data['plan_id'];
  263. });
  264. db('crm_receivables_plan_data')->insertAll($receivablesPlanData);
  265. return $data;
  266. } else {
  267. $this->error = '添加失败';
  268. return false;
  269. }
  270. }
  271. /**
  272. * 编辑回款计划
  273. * @author Michael_xu
  274. * @param
  275. * @return
  276. */
  277. public function updateDataById($param, $plan_id = '')
  278. {
  279. $userId = $param['user_id'];
  280. unset($param['user_id']);
  281. $dataInfo = $this->getDataById($plan_id);
  282. if (!$dataInfo) {
  283. $this->error = '数据不存在或已删除';
  284. return false;
  285. }
  286. $param['plan_id'] = $plan_id;
  287. //过滤不能修改的字段
  288. $unUpdateField = ['num','create_user_id','is_deleted','delete_time','delete_user_id'];
  289. foreach ($unUpdateField as $v) {
  290. unset($param[$v]);
  291. }
  292. // // 自动验证
  293. // $validate = validate($this->name);
  294. // if (!$validate->check($param)) {
  295. // $this->error = $validate->getError();
  296. // return false;
  297. // }
  298. // 数据验证
  299. $validateResult = $this->fieldDataValidate($param, 'crm_receivables_plan', $userId, $plan_id);
  300. if (!empty($validateResult)) {
  301. $this->error = $validateResult;
  302. return false;
  303. }
  304. if ($param['file_ids']) $param['file'] = arrayToString($param['file_ids']); //附件
  305. //提醒日期
  306. $param['remind_date'] = $param['remind'] ? date('Y-m-d',strtotime($param['return_date'])-86400*$param['remind']) : $param['return_date'];
  307. $fieldModel = new \app\admin\model\Field();
  308. // 处理部门、员工、附件、多选类型字段
  309. $arrFieldAtt = $fieldModel->getArrayField('crm_receivables_plan');
  310. foreach ($arrFieldAtt AS $key => $value) {
  311. $param[$value] = !empty($param[$value]) ? arrayToString($param[$value]) : '';
  312. }
  313. // 处理日期(date)类型
  314. $dateField = $fieldModel->getFieldByFormType('crm_receivables_plan', 'date');
  315. foreach ($dateField AS $key => $value) {
  316. $param[$value] = !empty($param[$value]) ? $param[$value] : null;
  317. }
  318. // 处理手写签名类型
  319. $handwritingField = $fieldModel->getFieldByFormType('crm_receivables_plan', 'handwriting_sign');
  320. foreach ($handwritingField AS $key => $value) {
  321. $param[$value] = !empty($param[$value]['file_id']) ? $param[$value]['file_id'] : '';
  322. }
  323. // 处理地址、定位、日期区间、明细表格类型字段
  324. $receivablesPlanData = [];
  325. $positionField = $fieldModel->getFieldByFormType('crm_receivables_plan', 'position');
  326. $locationField = $fieldModel->getFieldByFormType('crm_receivables_plan', 'location');
  327. $dateIntervalField = $fieldModel->getFieldByFormType('crm_receivables_plan', 'date_interval');
  328. $detailTableField = $fieldModel->getFieldByFormType('crm_receivables_plan', 'detail_table');
  329. foreach ($param AS $key => $value) {
  330. // 处理地址类型字段数据
  331. if (in_array($key, $positionField)) {
  332. if (!empty($value)) {
  333. $receivablesPlanData[] = [
  334. 'field' => $key,
  335. 'content' => json_encode($value, JSON_NUMERIC_CHECK),
  336. 'create_time' => time()
  337. ];
  338. $positionNames = array_column($value, 'name');
  339. $param[$key] = implode(',', $positionNames);
  340. } else {
  341. $param[$key] = '';
  342. }
  343. }
  344. // 处理定位类型字段数据
  345. if (in_array($key, $locationField)) {
  346. if (!empty($value)) {
  347. $receivablesPlanData[] = [
  348. 'field' => $key,
  349. 'content' => json_encode($value, JSON_NUMERIC_CHECK),
  350. 'create_time' => time()
  351. ];
  352. $param[$key] = $value['address'];
  353. } else {
  354. $param[$key] = '';
  355. }
  356. }
  357. // 处理日期区间类型字段数据
  358. if (in_array($key, $dateIntervalField)) {
  359. if (!empty($value)) {
  360. $receivablesPlanData[] = [
  361. 'field' => $key,
  362. 'content' => json_encode($value, JSON_NUMERIC_CHECK),
  363. 'create_time' => time()
  364. ];
  365. $param[$key] = implode('_', $value);
  366. } else {
  367. $param[$key] = '';
  368. }
  369. }
  370. // 处理明细表格类型字段数据
  371. if (in_array($key, $detailTableField)) {
  372. if (!empty($value)) {
  373. $receivablesPlanData[] = [
  374. 'field' => $key,
  375. 'content' => json_encode($value, JSON_NUMERIC_CHECK),
  376. 'create_time' => time()
  377. ];
  378. $param[$key] = $key;
  379. } else {
  380. $param[$key] = '';
  381. }
  382. }
  383. }
  384. if ($this->allowField(true)->save($param, ['plan_id' => $plan_id])) {
  385. $data = [];
  386. $data['plan_id'] = $plan_id;
  387. // 添加回款计划扩展数据
  388. db('crm_receivables_plan_data')->where('plan_id', $data['plan_id'])->delete();
  389. array_walk($receivablesPlanData, function (&$val) use ($data) {
  390. $val['plan_id'] = $data['plan_id'];
  391. });
  392. db('crm_receivables_plan_data')->insertAll($receivablesPlanData);
  393. return $data;
  394. } else {
  395. $this->error = '编辑失败';
  396. return false;
  397. }
  398. }
  399. /**
  400. * 回款计划数据
  401. * @param $id 回款计划ID
  402. * @return
  403. */
  404. public function getDataById($id = '')
  405. {
  406. $map['plan_id'] = $id;
  407. $dataInfo = $this->where($map)->find();
  408. if (!$dataInfo) {
  409. $this->error = '暂无此数据';
  410. return false;
  411. }
  412. $userModel = new \app\admin\model\User();
  413. $dataInfo['create_user_info'] = $userModel->getUserById($dataInfo['create_user_id']);
  414. $dataInfo['plan_id'] = $id;
  415. return $dataInfo;
  416. }
  417. //模拟自定义字段返回
  418. public function getField()
  419. {
  420. $field_arr = [
  421. '0' => [
  422. 'field' => 'customer_id',
  423. 'name' => '客户名称',
  424. 'form_type' => 'customer',
  425. 'setting' => []
  426. ],
  427. '1' => [
  428. 'field' => 'contract_id',
  429. 'name' => '合同名称',
  430. 'form_type' => 'contract',
  431. 'setting' => []
  432. ],
  433. '2' => [
  434. 'field' => 'money',
  435. 'name' => '计划回款金额',
  436. 'form_type' => 'floatnumber',
  437. 'setting' => []
  438. ],
  439. '3' => [
  440. 'field' => 'return_date',
  441. 'name' => '计划回款日期',
  442. 'form_type' => 'date',
  443. 'setting' => []
  444. ],
  445. '4' => [
  446. 'field' => 'return_type',
  447. 'name' => '计划回款方式',
  448. 'form_type' => 'select',
  449. 'setting' => '支付宝\n微信\n转账'
  450. ],
  451. '5' => [
  452. 'field' => 'remind',
  453. 'name' => '提前几日提醒',
  454. 'form_type' => 'number',
  455. 'setting' => []
  456. ],
  457. '6' => [
  458. 'field' => 'remark',
  459. 'name' => '备注',
  460. 'form_type' => 'textarea',
  461. 'setting' => []
  462. ],
  463. '7' => [
  464. 'field' => 'file',
  465. 'name' => '附件',
  466. 'form_type' => 'file',
  467. 'setting' => []
  468. ]
  469. ];
  470. return $field_arr;
  471. }
  472. }