FinancialProducts.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. <?php
  2. namespace app\cxinv\controller;
  3. use app\cxinv\model\ProductCheck;
  4. use app\cxinv\model\ProductFz;
  5. use app\cxinv\model\ProductsCombind;
  6. use think\App;
  7. class FinancialProducts extends Base
  8. {
  9. public function __construct(App $app)
  10. {
  11. parent::__construct($app);
  12. $this->model = new \app\cxinv\model\FinancialProducts();
  13. }
  14. public function List()
  15. {
  16. $param = $this->request->param(["skuCode" => "", "good_type" => "", "buyer_code" => "", "buyer_name" => "", "start" => "",
  17. "status" => "", "end" => "", "is_combind" => "","good_source"=>"" ,"basic_status" => "", "page" => 1, "size" => 15], "post", "trim");
  18. $where = [];
  19. if ($param['skuCode'] != "") $where[] = ["skuCode", "like", "%{$param['skuCode']}%"];
  20. if ($param['good_type'] != "") $where[] = ["good_type", "=", $param['good_type']];
  21. if($param['good_source']!="") $where[]= ["good_source","=",$param['good_source']];
  22. if ($param['buyer_code'] != "") $where[] = ["buyer_code", "=", $param['buyer_code']];
  23. if ($param['buyer_name'] != "") $where[] = ["buyer_name", "like", "%{$param['buyer_name']}%"];
  24. if ($param['start'] != "") $where[] = ["create_time", ">=", startTime($param['start'])];
  25. if ($param['end'] != "") $where[] = ["create_time", "<=", endTime($param['end'])];
  26. if ($param['is_combind'] != "") $where[] = ["is_combind", "=", $param['is_combind']];
  27. if ($param['basic_status'] !== "") $where[] = ["basic_status", "=", $param['basic_status']];
  28. if ($param['status'] != "") $where[] = ["status", "=", $param['status']];
  29. $list = $this->model
  30. ->with(["catInfo", "ProductsCombind" => ['products'], "ProductStock"])
  31. ->where($where)
  32. ->order("id desc")
  33. ->paginate(['page' => $param['page'], 'list_rows' => $param['size']]);
  34. return success('获取成功', ['list' => $list->items(), 'count' => $list->total()]);
  35. }
  36. public function create()
  37. {
  38. $param = $this->request->param(["skuCode" => "", "goodName" => "", "good_type" => "", "buyer_code" => "", "buyer_name" => "",
  39. "seller_code" => "", "seller_name" => "", "good_source" => "", "inv_good_name" => "", "is_combind" => "", "spec" => "", "good_code" => "",
  40. "unit" => "", "unit_price" => "", "subunit_price" => "", "unit_weight" => "", "cat_code" => "", "cat_tax" => "", "inv_type" => "",
  41. "basic_status" => 1, 'spectral' => '', "childArr" => []], "post", "trim");
  42. $valid = $this->validate($param, [
  43. 'skuCode|商品编号' => 'require|max:255',
  44. 'goodName|商品名称' => 'require|max:255',
  45. 'good_type|商品类型' => 'require|in:1,2,3',
  46. 'buyer_code|买方公司纳税识别号' => 'require|max:255',
  47. 'buyer_name|买方公司名称' => 'require|max:255',
  48. 'seller_code|卖方公司纳税识别号' => 'require|max:255',
  49. 'seller_name|卖方公司名称' => 'require|max:255',
  50. 'good_source|商品来源' => 'require|in:1,2',
  51. 'inv_good_name|发票商品名称' => 'require|max:255',
  52. 'is_combind|是否组合商品' => 'require|in:0,1',
  53. 'spec|规格' => 'max:255',
  54. 'good_code|商品代码' => 'max:255',
  55. 'unit|单位' => 'require|max:255',
  56. 'unit_price|成本税前单价' => 'require|float',
  57. 'subunit_price|成本税后单价' => 'require|float',
  58. 'unit_weight|重量' => 'float',
  59. "spectral|分光" => 'max:255',
  60. 'cat_code|进项类目' => 'require|max:255',
  61. 'cat_tax|进项税率' => 'require|max:255',
  62. 'inv_type|发票类型' => 'require|max:255',
  63. 'basic_status|进项成本状态' => 'require|in:1,2',
  64. 'childArr|商品子商品' => 'requireIf:is_combind,1|array'
  65. ]);
  66. if ($valid !== true) return error($valid);
  67. $param['apply_id'] = $this->uid;
  68. $param['apply_name'] = $this->uname;
  69. if ($param['is_combind'] == 1) {
  70. foreach ($param['childArr'] as $key => $item) {
  71. $iteminfo = $this->model->where('id', $item['child_id'])->findOrEmpty();
  72. if ($iteminfo->isEmpty()) return error("子商品{$iteminfo->skuCode}不存在");
  73. if ($item['child_num'] <= 0) return error("子商品{$iteminfo->skuCode}数量必须大于0");
  74. if ($iteminfo->basic_status == 2) return error("子商品{$iteminfo->skuCode}成本状态为预估成本");
  75. $param['childArr'][$key]['skuCode'] = $iteminfo->skuCode;
  76. }
  77. }
  78. $where = $param;
  79. unset($where['childArr']);
  80. $isT = $this->model->where($where)->findOrEmpty();
  81. if (!$isT->isEmpty()) return error("商品编号{$param['skuCode']}已存在");
  82. $this->model->startTrans();
  83. try {
  84. $res = $this->model->create($param);
  85. if ($res->isEmpty()) throw new \Exception('添加失败');
  86. if ($param['is_combind'] == 1) {
  87. $parentid = $res->id;
  88. $childRes = (new ProductsCombind)->saveAll(array_map(function ($item) use ($parentid) {
  89. $item['parent_id'] = $parentid;
  90. return $item;
  91. }, $param['childArr']));
  92. if ($childRes->isEmpty()) throw new \Exception('添加失败');
  93. }
  94. $this->model->commit();
  95. } catch (\Exception $e) {
  96. $this->model->rollback();
  97. return error($e->getMessage());
  98. }
  99. return success('添加成功');
  100. }
  101. public function update()
  102. {
  103. $param = $this->request->param(["id" => "", "skuCode" => "", "goodName" => "", "good_type" => "", "buyer_code" => "", "buyer_name" => "",
  104. "seller_code" => "", "seller_name" => "", "good_source" => "", "inv_good_name" => "", "is_combind" => "", "spec" => "", "good_code" => "",
  105. "unit" => "", "unit_price" => "", "subunit_price" => "", "unit_weight" => "", "cat_code" => "", "cat_tax" => "", "inv_type" => "",
  106. "basic_status" => "", "childArr" => []], "post", "trim");
  107. $valid = $this->validate($param, [
  108. 'id|商品ID' => 'require|integer',
  109. 'skuCode|商品编号' => 'require|max:255',
  110. 'goodName|商品名称' => 'require|max:255',
  111. 'good_type|商品类型' => 'require|in:1,2,3',
  112. 'buyer_code|买方公司纳税识别号' => 'require|max:255',
  113. 'buyer_name|买方公司名称' => 'require|max:255',
  114. 'seller_code|卖方公司纳税识别号' => 'require|max:255',
  115. 'seller_name|卖方公司名称' => 'require|max:255',
  116. 'good_source|商品来源' => 'require|in:1,2',
  117. 'inv_good_name|发票商品名称' => 'require|max:255',
  118. 'is_combind|是否组合商品' => 'require|in:0,1',
  119. 'spec|规格' => 'max:255',
  120. 'good_code|商品代码' => 'max:255',
  121. 'unit|单位' => 'require|max:255',
  122. 'unit_price|成本税前单价' => 'require|float',
  123. 'subunit_price|成本税后单价' => 'require|float',
  124. 'unit_weight|重量' => 'float',
  125. "spectral|分光" => 'max:255',
  126. 'cat_code|进项类目' => 'require|max:255',
  127. 'cat_tax|进项税率' => 'require|max:255',
  128. 'inv_type|发票类型' => 'require|max:255',
  129. 'basic_status|进项成本状态' => 'require|in:1,2',
  130. 'childArr|商品子商品' => 'requireIf:is_combind,1|array'
  131. ]);
  132. if ($valid !== true) return error($valid);
  133. $info = $this->model->with(['ProductsCombind'])->findOrEmpty($param['id']);
  134. if ($info->isEmpty()) return error('数据不存在');
  135. if ($info->is_combind == 1 || $param['is_combind'] == 1) {
  136. $childIds = array_column($info->ProductsCombind->toArray(), "id");
  137. $paramChilds = array_column($param['childArr'], 'id');
  138. $delIds = array_diff($childIds, $paramChilds);
  139. $add = [];
  140. foreach ($param['childArr'] as $key => $item) {
  141. $iteminfo = $this->model->where('id', $item['child_id'])->findOrEmpty();
  142. if ($iteminfo->isEmpty()) return error("子商品{$iteminfo->skuCode}不存在");
  143. if ($item['child_num'] <= 0) return error("子商品{$iteminfo->skuCode}数量必须大于0");
  144. if ($iteminfo->basic_status == 2) return error("子商品{$iteminfo->skuCode}成本状态为预估成本");
  145. $item['id'] = $item['id'] ?? null;
  146. $item['parent_id'] = $param['id'];
  147. $param['childArr'][$key]['skuCode'] = $iteminfo->skuCode;
  148. $add[] = $item;
  149. }
  150. }
  151. $where = $param;
  152. unset($where['childArr']);
  153. unset($where['id']);
  154. $isT = $this->model->where($where)->where("id", "<>", $param['id'])->findOrEmpty();
  155. if (!$isT->isEmpty()) return error("商品编号{$param['skuCode']}已存在");
  156. $this->model->startTrans();
  157. try {
  158. $res = $info->save($param);
  159. if (!$res) throw new \Exception('更新失败');
  160. if ($param['is_combind'] == 1) {
  161. if (!empty($delIds)) ProductsCombind::where(["parent_id" => $param['id'], "id" => $delIds])->delete();
  162. if (!empty($add)) {
  163. $childRes = (new ProductsCombind)->saveAll($add);
  164. if ($childRes->isEmpty()) throw new \Exception('更新失败');
  165. }
  166. }
  167. $this->model->commit();
  168. } catch (\Exception $e) {
  169. $this->model->rollback();
  170. return error($e->getMessage());
  171. }
  172. return success('更新成功');
  173. }
  174. public function info()
  175. {
  176. $id = $this->request->param("id", "0", "int");
  177. $info = $this->model->with(["catInfo", "ProductsCombind" => ['products'], 'ProductStock'])->findOrEmpty($id);
  178. if ($info->isEmpty()) return error('数据不存在');
  179. return success('获取成功', $info);
  180. }
  181. public function delete()
  182. {
  183. $id = $this->request->param("id", "0", "int");
  184. $info = $this->model->findOrEmpty($id);
  185. if ($info->isEmpty()) return error('数据不存在');
  186. $res = $info->delete();
  187. if ($info->is_combind == 1) {
  188. ProductsCombind::where("parent_id", $id)->delete();
  189. }
  190. return $res ? success('删除成功') : error('删除失败');
  191. }
  192. public function status()
  193. {
  194. $param = $this->request->param(["id" => "", "status" => ""], "post", "trim");
  195. $valid = $this->validate($param, [
  196. 'id|商品ID' => 'require|integer',
  197. 'status|状态' => 'require|in:0,1'
  198. ]);
  199. if ($valid !== true) return error($valid);
  200. $info = $this->model->findOrEmpty($param['id']);
  201. if ($info->isEmpty()) return error('数据不存在');
  202. $res = $info->save(['status' => $param['status']]);
  203. return $res ? success('修改成功') : error('修改失败');
  204. }
  205. public function getGoods()
  206. {
  207. $param = $this->request->param(["skuCode" => "", "good_type" => "", "buyer_code" => "", "seller_code" => "", "start" => "",
  208. "status"=>"", "end" => "", "is_combind" => "","good_source"=>"", "basic_status" => "", "limit" => 100], "post", "trim");
  209. $valid = $this->validate($param, [
  210. 'skuCode|商品编号' => 'max:255',
  211. 'good_type|商品类型' => 'in:1,2,3',
  212. 'buyer_code|买方公司纳税识别号' => 'max:255',
  213. 'seller_code|卖方公司纳税识别号' => 'max:255',
  214. 'start|开始时间' => 'date',
  215. 'end|结束时间' => 'date',
  216. 'is_combind|是否组合商品' => 'in:0,1',
  217. 'basic_status|进项成本状态' => 'in:1,2',
  218. 'status|状态' => 'in:0,1',
  219. ]);
  220. if ($valid !== true) return error($valid);
  221. $where = [];
  222. if ($param['basic_status'] !== '') $where[] = ['basic_status', '=', $param['basic_status']];
  223. if($param['good_source']!="") $where[]= ["good_source","=",$param['good_source']];
  224. if ($param['status'] !== '') $where[] = ['status', '=', $param['status']];
  225. if ($param['skuCode'] !== '') $where[] = ['skuCode', 'like', "%{$param['skuCode']}%"];
  226. if ($param['good_type'] !== '') $where[] = ['good_type', '=', $param['good_type']];
  227. if ($param['buyer_code'] !== '') $where[] = ['buyer_code', '=', $param['buyer_code']];
  228. if ($param['seller_code'] !== '') $where[] = ['seller_code', '=', $param['seller_code']];
  229. if ($param['is_combind'] !== '') $where[] = ['is_combind', '=', $param['is_combind']];
  230. if($param['start'] !== '') $where[] = ['create_time', '>=', startTime($param['start'])];
  231. if($param['end'] !== '') $where[] = ['create_time', '<=', endTime($param['end'])];
  232. $list = $this->model->with(['catInfo', 'ProductStock', 'ProductsCombind' => ['products']])->where($where)->order('id desc')->limit($param['limit'])->select();
  233. return success('获取成功', $list);
  234. }
  235. public function combindGood()
  236. {
  237. $param = $this->request->param(["parent_id" => "", "childArr" => []], "post", "trim");
  238. $valid = $this->validate($param, [
  239. 'parent_id|商品ID' => 'require|integer',
  240. 'childArr|子商品' => 'require|array'
  241. ]);
  242. if ($valid !== true) return error($valid);
  243. $parent = $this->model->findOrEmpty($param['pid']);
  244. if ($parent->isEmpty()) return error('数据不存在');
  245. $combind = new ProductsCombind();
  246. $ist = $combind->where(['parent_id' => $param['parent_id']])->column("child_id");
  247. $del = array_diff($ist, array_column($param['childArr'], 'child_id'));
  248. $add = [];
  249. foreach ($param['childArr'] as $item) {
  250. $vali = $this->validate($item, [
  251. 'child_id|子商品ID' => 'require|integer',
  252. 'child_num|子商品数量' => 'require|integer'
  253. ]);
  254. if ($vali !== true) return error($vali);
  255. $add[] = [
  256. "id" => $ist[$item['child_id']] ?? null,
  257. "parent_id" => $param['parent_id'],
  258. "child_num" => $item['child_num'],
  259. "child_id" => $item['child_id']
  260. ];
  261. }
  262. $this->model->startTrans();
  263. try {
  264. if (!empty($del)) $combind->where(["parent_id" => $param['parent_id'], "child_id" => $del])->delete();
  265. if (!empty($add)) $combind->saveAll($add);
  266. $this->model->commit();
  267. } catch (\Exception $e) {
  268. $this->model->rollback();
  269. return error($e->getMessage());
  270. }
  271. return success('修改成功');
  272. }
  273. public function CheckCreate()
  274. {
  275. $param = $this->request->param(["product_id" => "", 'check_num' => "", "check_type" => 0, "fz_date" => ""], "post", "trim");
  276. $valid = $this->validate($param, [
  277. 'product_id|商品ID' => 'require|integer',
  278. 'check_num|盘点数量' => 'require|float',
  279. 'check_type|盘点类型' => 'require|in:0,1,2',
  280. 'fz_date|调整单封账日期' => 'requireIf:check_type,2|max:255'
  281. ]);
  282. if ($valid !== true) return error($valid);
  283. $product = $this->model->with(['catInfo', 'ProductStock'])->findOrEmpty($param['product_id']);
  284. if ($product->isEmpty()) return error('商品数据不存在');
  285. if ($product->is_combind == 1) return error('组合商品不允许盘点');
  286. if ($product->basic_status ==2) return error('预估成本商品不允许盘点');
  287. if ($param['check_type'] == 2) {
  288. $isT = ProductFz::where(["fz_date" => $param['fz_date'], "company_code" => $product->buyer_code])->findOrEmpty();
  289. if (!$isT->isEmpty() && $isT->status != 0) return error('该日期已封账,不允许再新增');
  290. }
  291. $diff_num = bcsub($param['check_num'], $product->residue_stock ?? "0", 8);
  292. if ($diff_num == 0) return error('盘点数量与库存数量一致,无需盘点');
  293. $is_diff = $diff_num > 0 ? 1 : 0;
  294. $data = [
  295. 'checkCode' => makeNo("CWPD"),
  296. 'product_id' => $param['product_id'],
  297. 'check_num' => $param['check_num'],
  298. 'diff_num' => $diff_num,
  299. 'stock_num' => $product->residue_stock ?? "0",
  300. 'unit_price' => $product->unit_price,
  301. 'diff_fee' => bcmul($diff_num, $product->unit_price, 8),
  302. 'check_type' => $param['check_type'],
  303. 'fz_date' => $param['fz_date'],
  304. 'is_diff' => $is_diff,
  305. "apply_id" => $this->uid,
  306. "apply_name" => $this->uname
  307. ];
  308. $this->model->startTrans();
  309. try {
  310. $use = ProductCheck::create($data);
  311. if ($use->isEmpty()) throw new \think\Exception("新增盘点单失败");
  312. } catch (\Exception $e) {
  313. $this->model->rollback();
  314. return error($e->getMessage());
  315. }
  316. $this->model->commit();
  317. return success('盘点单创建成功');
  318. }
  319. public function CheckBatch()
  320. {
  321. $list = $this->request->param("list", [], "trim");
  322. if (empty($list)) return error('请选择要批量盘点的商品');
  323. $create = [];
  324. foreach ($list as $item) {
  325. // product_id check_num balance_num check_type fz_date
  326. $valid = $this->validate($item, [
  327. 'product_id|商品ID' => 'require|integer',
  328. 'check_num|盘点数量' => 'require|float',
  329. 'balance_num|库存数量' => 'require|float',
  330. 'check_type|盘点类型' => 'require|in:0,1,2',
  331. 'fz_date|调整单封账日期' => 'requireIf:check_type,2|max:255'
  332. ]);
  333. if ($valid !== true) return error($valid);
  334. $product = $this->model->with(['catInfo', 'ProductStock'])->findOrEmpty($item['product_id']);
  335. if ($product->isEmpty()) return error($item['product_id'] . '商品数据不存在');
  336. if ($product->is_combind == 1) return error($item['goodName'] . '组合商品不允许盘点');
  337. if ($product->basic_status ==2) return error($item['goodName'] . '预估成本商品不允许盘点');
  338. if ($item['check_type'] == 2) {
  339. $isT = ProductFz::where(["fz_date" => $item['fz_date'], "company_code" => $product->buyer_code])->findOrEmpty();
  340. if (!$isT->isEmpty() && $isT->status != 0) return error('该账期已封账,不允许再新增');
  341. }
  342. if ($item['balance_num'] != $product->residue_stock ?? "0") return error($product['goodName'] . '库存数量与盘点库存数量不一致');
  343. $diff_num = bcsub($item['check_num'], $item['balance_num'], 8);
  344. $isdiff = $diff_num > 0 ? 1 : 0;
  345. $create[] = [
  346. 'checkCode' => makeNo("CWPD"),
  347. 'product_id' => $item['product_id'],
  348. 'check_num' => $item['check_num'],
  349. 'diff_num' => $diff_num,
  350. 'stock_num' => $product->residue_stock ?? "0",
  351. 'unit_price' => $product->unit_price,
  352. 'diff_fee' => bcmul($diff_num, $product->unit_price, 8),
  353. 'check_type' => $item['check_type'],
  354. 'fz_date' => $item['fz_date'],
  355. 'is_diff' => $isdiff,
  356. "apply_id" => $this->uid,
  357. "apply_name" => $this->uname
  358. ];
  359. }
  360. $this->model->startTrans();
  361. try {
  362. $use = (new ProductCheck)->saveAll($create);
  363. if ($use->isEmpty()) throw new \think\Exception("批量新增盘点单失败");
  364. $this->model->commit();
  365. } catch (\Exception $e) {
  366. $this->model->rollback();
  367. return error($e->getMessage());
  368. }
  369. return success('批量盘点单创建成功');
  370. }
  371. public function CheckList()
  372. {
  373. $param = $this->request->param(["checkCode" => "", "check_type" => "", "start" => "", "end" => "", "skuCode" => "", "buyer_code" => "", "page" => 1, "size" => 20]
  374. , "post", "trim");
  375. $where = [];
  376. if ($param['checkCode'] !== "") $where[] = ['checkCode', 'like', '%' . $param['checkCode'] . '%'];
  377. if ($param['check_type'] !== "") $where[] = ['check_type', '=', $param['check_type']];
  378. if (!empty($param['start']) && !empty($param['end'])) $where[] = ['product_check.create_time', 'between', [startTime($param['start']), endTime($param['end'])]];
  379. if ($param['skuCode'] !== "") $where[] = ['product.skuCode', 'like', '%' . $param['skuCode'] . '%'];
  380. if ($param['buyer_code'] !== "") $where[] = ['product.buyer_code', '=', $param['buyer_code']];
  381. $list = ProductCheck::with(['product' => ['ProductStock']])
  382. ->withJoin(['product'], 'LEFT')
  383. ->where($where)
  384. ->order('id desc')
  385. ->paginate(['page' => $param['page'], 'list_rows' => $param['size']]);
  386. return success("获取成功", ["list" => $list->items(), "count" => $list->total()]);
  387. }
  388. public function CheckInfo()
  389. {
  390. $id = $this->request->param('id', 0, 'intval');
  391. if (empty($id)) return error('盘点单ID不能为空');
  392. $info = ProductCheck::with(['product' => ['ProductStock']])
  393. ->findOrEmpty($id);
  394. if ($info->isEmpty()) return error('盘点单不存在');
  395. return success("获取成功", $info);
  396. }
  397. }