StoreCheckingReceiveController.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. <?php
  2. namespace App\Http\Controllers;
  3. use App\Imports\StoreCheckingReceiveSheets;
  4. use App\Services\CommodityService;
  5. use App\Services\LogService;
  6. use App\Services\OracleDocAsnDetailService;
  7. use App\Services\StoreCheckingReceiveService;
  8. use App\StoreCheckingReceive;
  9. use Exception;
  10. use Illuminate\Http\Request;
  11. use Illuminate\Support\Facades\Cache;
  12. use Illuminate\Support\Facades\Gate;
  13. use Illuminate\Support\Facades\Http;
  14. use Maatwebsite\Excel\Facades\Excel;
  15. use Oursdreams\Export\Export;
  16. class StoreCheckingReceiveController extends Controller
  17. {
  18. public function mission(Request $request){
  19. if(!Gate::allows('入库管理-盘收一体-盘收-查看')){ return view('store/index'); }
  20. /** @var StoreCheckingReceiveService $service */
  21. $service = app('StoreCheckingReceiveService');
  22. $params = $request->input();
  23. $storeCheckingReceives = $service->paginate($params);
  24. $owners = app('OwnerService')->getIntersectPermitting();
  25. return view('store.checkingReceive.mission',compact('storeCheckingReceives','params','owners'));
  26. }
  27. public function import(Request $request){
  28. if(!Gate::allows('入库管理-盘收一体-盘收-编辑')){ return ['success'=>false, 'data'=>'无权操作!']; }
  29. $fileSuffix=$request->file('file')->getClientOriginalExtension();
  30. if ($fileSuffix != 'xlsx' && $fileSuffix != 'xls' && $fileSuffix != 'csv')
  31. return ['success'=>false,'data'=>'不支持该文件类型'];
  32. ini_set('max_execution_time',2500);
  33. ini_set('memory_limit','1526M');
  34. $fileSuffix = ucwords($fileSuffix);
  35. Excel::import(new StoreCheckingReceiveSheets(),$request->file('file')->path(),null,$fileSuffix);
  36. if (Cache::has('storeCheckingReceive')){
  37. return Cache::pull('storeCheckingReceive');
  38. }
  39. return ["success"=>false, "data"=>"读取导入文件错误"];
  40. }
  41. public function show($id,Request $request){
  42. if(!Gate::allows('入库管理-盘收一体-盘收-查看')){ return redirect(url('/')); }
  43. /** @var StoreCheckingReceiveService $service */
  44. $service = app('StoreCheckingReceiveService');
  45. $withs = ['owner','storeCheckingReceiveItems'=>function($query){
  46. $query->with(['commodity'=>function($builder) {
  47. $builder->with('barcodes');
  48. }]);
  49. }];
  50. $storeCheckingReceive = $service->find($id,$withs);
  51. $is_show = $request->is_show ?? true;
  52. if ($storeCheckingReceive->owner ?? false){
  53. $commodityController = new CommodityController();
  54. $sku = [];
  55. foreach ($storeCheckingReceive->storeCheckingReceiveItems as $item){
  56. $sku[] = $item->commodity->sku ?? "";
  57. }
  58. $commodityController->syncOwnerCommodities($storeCheckingReceive->owner->id, $storeCheckingReceive->owner->code, $sku);
  59. }
  60. return view('store.checkingReceive.show',compact('storeCheckingReceive','is_show'));
  61. }
  62. public function insertItem(Request $request){
  63. if(!Gate::allows('入库管理-盘收一体-盘收-编辑')){ return ['success'=>false, 'data'=>'无权操作!']; }
  64. $mission_id = $request->mission_id ?? false;
  65. $goods = $request->goods ?? false;
  66. if (!($goods["amount"] ?? false))$goods["amount"] = 1;
  67. if (!$mission_id || !$goods)return ['success'=>false, 'data'=>'参数传递错误!'];
  68. $withs = ['owner','storeCheckingReceiveItems'=>function($query){
  69. $query->with(['commodity'=>function($builder) {
  70. $builder->with('barcodes');
  71. }]);
  72. }];
  73. $storeCheckingReceive = app('StoreCheckingReceiveService')->find($mission_id,$withs);
  74. if (!$storeCheckingReceive)return ['success'=>false, 'data'=>'盘收任务不存在'];
  75. if ($storeCheckingReceive->status == '已收货')return ['success'=>false, 'data'=>'盘收任务已结束'];
  76. $storeCheckingReceiveItem = null;
  77. $is_receive_diff = "否";
  78. $is_asn_diff = "否";
  79. $is_inventory_complete = true;
  80. foreach ($storeCheckingReceive->storeCheckingReceiveItems as $item){
  81. if (!$item->commodity)continue;
  82. if (count($item->commodity->barcodes) < 1)continue;
  83. foreach ($item->commodity->barcodes as $barcode){
  84. if ($barcode->code == $goods['barcode']){
  85. if ($goods['batch_number'] == $item->batch_code &&
  86. $goods['produce_date'] == $item->produced_at &&
  87. $goods['unique_code'] == $item->unique_code &&
  88. $goods['valid_date'] == $item->invalid_at){
  89. $storeCheckingReceiveItem = $item;
  90. break;
  91. }
  92. }
  93. }
  94. if ($storeCheckingReceiveItem)continue;
  95. if ($item->imported_diff_amount > 0)$is_receive_diff = "是";
  96. if (!$item->counted_amount)$is_inventory_complete = false;
  97. }
  98. if ($storeCheckingReceiveItem){
  99. $counted_amount = $storeCheckingReceiveItem->counted_amount+$goods['amount'];
  100. $params = ['counted_amount'=>$counted_amount];
  101. if (!$storeCheckingReceiveItem->imported_amount){
  102. $params['imported_amount'] = 0;
  103. $params['imported_diff_amount'] = $counted_amount;
  104. }else $params['imported_diff_amount'] = $counted_amount-$storeCheckingReceiveItem->imported_amount;
  105. if ($storeCheckingReceiveItem->asn_amount)$params['asn_diff_amount'] = $counted_amount-$storeCheckingReceiveItem->asn_amount;
  106. if (!$storeCheckingReceiveItem->bin_number && $goods['bin_number'])$params['bin_number'] = $goods['bin_number'];
  107. if (isset($params['imported_diff_amount']) && $params['imported_diff_amount'] > 0)$is_receive_diff = "是";
  108. if (isset($params['asn_diff_amount']) && $params['asn_diff_amount'] > 0)$is_asn_diff = "是";
  109. $item = app('StoreCheckingReceiveItemService')->updateFind($storeCheckingReceiveItem,$params);
  110. app('LogService')->log(__METHOD__,"清点数量",json_encode($item,JSON_UNESCAPED_UNICODE));
  111. switch ($storeCheckingReceive->status){
  112. case '已导入':
  113. $SCR = app('StoreCheckingReceiveService')->updateFind($storeCheckingReceive,['status'=>'清点中']);
  114. app('LogService')->log(__METHOD__,"修改盘收任务状态为清点中",json_encode($SCR,JSON_UNESCAPED_UNICODE));
  115. break;
  116. case '清点中':
  117. $res = [];
  118. if ($is_inventory_complete){
  119. $res['status']='已清点';
  120. }
  121. //差异存在时 判断差异是否变化,变化则更新,差异不存在时 判断差异是否存在 存在则更新
  122. if (($storeCheckingReceive->is_receive_diff && $storeCheckingReceive->is_receive_diff != $is_receive_diff)
  123. || (!$storeCheckingReceive->is_receive_diff && isset($params['imported_diff_amount'])))
  124. $res['is_receive_diff'] = $is_receive_diff;
  125. if (($storeCheckingReceive->is_asn_diff && $storeCheckingReceive->is_asn_diff != $is_asn_diff)
  126. || (!$storeCheckingReceive->is_asn_diff && isset($params['asn_diff_amount'])))
  127. $res['is_receive_diff'] = $is_receive_diff;
  128. if (count($res) > 0){
  129. $SCR = app('StoreCheckingReceiveService')->updateFind($storeCheckingReceive,$res);
  130. app('LogService')->log(__METHOD__,"修改盘收任务",json_encode($SCR,JSON_UNESCAPED_UNICODE));
  131. }
  132. break;
  133. }
  134. return ['success'=>true, 'type'=>"update", 'data'=>$item];
  135. }
  136. $commodity = app('CommodityService')->ownerBarcodeSeekCommodityFirst(['id'=>$storeCheckingReceive->owner_id], $goods['barcode']);
  137. if (!$commodity) {
  138. if (!$storeCheckingReceive->owner) return ['success'=>false, 'data'=>'未找到货主'];
  139. $basSku = app('OracleBasSkuService')->first(['customerid'=>$storeCheckingReceive->owner->code, "barcode"=>$goods['barcode']]);
  140. if ($basSku){
  141. $commodity = app('CommodityService')->firstOrCreate(['owner_id'=>$storeCheckingReceive->owner_id, 'sku'=>$basSku->sku],[
  142. "name"=>$basSku->descr_c,
  143. "sku"=>$basSku->sku,
  144. "owner_id"=>$storeCheckingReceive->owner_id,
  145. 'length' => $basSku->skulength,
  146. 'width' => $basSku->skuwidth,
  147. 'height' => $basSku->skuhigh,
  148. 'volumn' => $basSku->cube
  149. ]);
  150. if ($commodity) app('CommodityBarcodeService')->firstOrCreate(['commodity_id'=>$commodity->id, 'code'=>$goods['barcode']]);
  151. }else{
  152. $commodity = app('CommodityService')->createTemporaryCommodity([
  153. "sku"=>$goods['barcode'],
  154. "owner_id"=>$storeCheckingReceive->owner_id,
  155. ]);
  156. app('CommodityBarcodeService')->create([
  157. "commodity_id"=>$commodity->id,
  158. "code" => $goods['barcode'],
  159. ]);
  160. }
  161. };
  162. $item = app('StoreCheckingReceiveItemService')->create([
  163. 'store_checking_receive_id' => $mission_id,
  164. 'bin_number' => $goods['bin_number'],
  165. 'commodity_id' => $commodity->id,
  166. 'imported_amount' => 0,
  167. 'imported_diff_amount' => $goods['amount'],
  168. 'produced_at' => $goods['produce_date'],
  169. 'invalid_at' => $goods['valid_date'],
  170. 'batch_code' => $goods['batch_number'],
  171. 'unique_code' => $goods['unique_code'],
  172. 'counted_amount' => $goods['amount'],
  173. ]);
  174. $item->load(['commodity'=>function($query){
  175. $query->with('barcodes');
  176. }]);
  177. switch ($storeCheckingReceive->status){
  178. case '已导入':
  179. $SCR = app('StoreCheckingReceiveService')->updateFind($storeCheckingReceive,['status'=>'清点中']);
  180. app('LogService')->log(__METHOD__,"修改盘收任务状态为清点中",json_encode($SCR,JSON_UNESCAPED_UNICODE));
  181. break;
  182. case '清点中':
  183. $res = [];
  184. if ($is_inventory_complete){
  185. $res['status']='已清点';
  186. }
  187. //差异存在时 判断差异是否变化,变化则更新,差异不存在时 判断差异是否存在 存在则更新
  188. if ($is_receive_diff == "否")$is_receive_diff = $item->imported_diff_amount>0 ? "是" : "否";
  189. if ($storeCheckingReceive->is_receive_diff != $is_receive_diff)
  190. $res['is_receive_diff'] = $is_receive_diff;
  191. if ($storeCheckingReceive->is_asn_diff && ($storeCheckingReceive->is_asn_diff != $is_asn_diff))
  192. $res['is_receive_diff'] = $is_receive_diff;
  193. if (count($res) > 0){
  194. $SCR = app('StoreCheckingReceiveService')->updateFind($storeCheckingReceive,$res);
  195. app('LogService')->log(__METHOD__,"修改盘收任务",json_encode($SCR,JSON_UNESCAPED_UNICODE));
  196. }
  197. break;
  198. }
  199. return ['success'=>true, 'type'=>'create', 'data'=>$item];
  200. }
  201. public function export(Request $request){
  202. if(!Gate::allows('入库管理-盘收一体-盘收-查看')){ return redirect(url('/')); }
  203. $id = $request->mission_id ?? false;
  204. $withs = ['owner','storeCheckingReceiveItems'=>function($query){
  205. $query->with(['commodity'=>function($builder) {
  206. $builder->with('barcodes');
  207. }]);
  208. }];
  209. $storeCheckingReceive = app('StoreCheckingReceiveService')->find($id,$withs);
  210. if (!$storeCheckingReceive) new \Exception('盘收任务不存在');
  211. $row = ['ID','格口号','商品名','商品条码','导入数量','实盘数量','ASN数量','导入差异数','ASN差异数','生产日期','有效日期','批次号','唯一码'];
  212. $list = [];
  213. foreach ($storeCheckingReceive->storeCheckingReceiveItems as $item){
  214. $code = '';
  215. foreach ($item->commodity ? $item->commodity->barcodes : [] as $barcode){
  216. $code .= $barcode->code;
  217. }
  218. $list[] = [
  219. $item->id,
  220. $item->bin_number,
  221. $item->commodity ? $item->commodity->name : '',
  222. $code,
  223. $item->imported_amount,
  224. $item->counted_amount,
  225. $item->asn_amount,
  226. $item->imported_diff_amount,
  227. $item->asn_diff_amount,
  228. $item->produced_at,
  229. $item->invalid_at,
  230. $item->batch_code,
  231. $item->unique_code,
  232. ];
  233. }
  234. return Export::make($row,$list,"盘收任务单");
  235. }
  236. public function resetAmount(Request $request){
  237. if(!Gate::allows('入库管理-盘收一体-盘收-编辑')){ return ['success'=>false, 'data'=>'无权操作!']; }
  238. $id = $request->mission_id ?? false;
  239. if (!$id) return ['success'=>false, 'data'=>'盘收任务不存在'];
  240. app('StoreCheckingReceiveItemService')->update(['store_checking_receive_id'=>$id],[
  241. 'counted_amount'=>0,
  242. 'imported_diff_amount'=>null,
  243. 'asn_diff_amount'=>null,
  244. 'bin_number'=>null,
  245. ]);
  246. app('LogService')->log(__METHOD__,"重置盘收任务所有数量","store_checking_receive_id:".$id);
  247. return ['success'=>true];
  248. }
  249. public function matchASN(Request $request){
  250. if(!Gate::allows('入库管理-快速入库-录入')){ return ['success'=>false, 'data'=>'无权操作!']; }
  251. $asn = $request->asn ?? false;
  252. $id = $request->mission_id ?? false;
  253. if (!$asn || !$id)return ['success'=>false, 'data'=>'传递参数错误'];
  254. $withs = ['owner','storeCheckingReceiveItems'=>function($query){
  255. $query->with(['commodity'=>function($builder) {
  256. $builder->with('barcodes');
  257. }]);
  258. }];
  259. $storeCheckingReceive = app('StoreCheckingReceiveService')->find($id,$withs);
  260. if (!$storeCheckingReceive) return ['success'=>false, 'data'=>'未找到此盘点任务!'];
  261. if ($storeCheckingReceive->status == '已收货')return ['success'=>false, 'data'=>'盘收任务已结束'];
  262. /** @var OracleDocAsnDetailService $oracleDocAsnDetailService */
  263. $oracleDocAsnDetailService = app('OracleDocAsnDetailService');
  264. $docAsnDetails = $oracleDocAsnDetailService->get([
  265. 'asnno'=>$asn,
  266. 'customerid'=>$storeCheckingReceive->owner ? $storeCheckingReceive->owner->code : null],[
  267. 'asnno','customerid','asnlineno','sku','expectedqty'
  268. ]);
  269. if (count($docAsnDetails) < 1) return ['success'=>false, 'data'=>'该货主下此ASN号不存在'];
  270. $diffAmount = null;
  271. $skus = [];
  272. foreach ($docAsnDetails as $detail){
  273. if ($skus[$detail->sku] ?? false) $skus[$detail->sku] += $detail->expectedqty;
  274. else $skus[$detail->sku] = $detail->expectedqty;
  275. }
  276. $deleteItems = [];
  277. $updateItems = [];
  278. $updateItems[] = ['id','asn_amount','asn_diff_amount'];
  279. foreach ($storeCheckingReceive->storeCheckingReceiveItems as $item){
  280. if (!($item->commodity ? $item->commodity->sku : null))continue;
  281. if ($storeCheckingReceive->asn && ($item->asn_amount != null)
  282. && (!($item->counted_amount ?? false))){
  283. $deleteItems[] = $item->id;
  284. continue;
  285. }
  286. if ($skus[$item->commodity->sku] ?? false){
  287. $asn_diff_amount = $skus[$item->commodity->sku] - $item->counted_amount;
  288. $updateItems[] = [
  289. 'id'=>$item->id,
  290. 'asn_amount'=>$skus[$item->commodity->sku],
  291. 'asn_diff_amount'=>$asn_diff_amount,
  292. ];
  293. $item->asn_diff_amount = $asn_diff_amount;
  294. unset($skus[$item->commodity->sku]);
  295. }
  296. if ($item->asn_diff_amount)$diffAmount += $item->asn_diff_amount;
  297. }
  298. if (count($updateItems) > 0){
  299. app('StoreCheckingReceiveItemService')->batchUpdate($updateItems);
  300. app('LogService')->log(__METHOD__,"匹配ASN-批量更新ASN数量",json_encode($updateItems));
  301. }
  302. if (count($deleteItems) > 0){
  303. app('StoreCheckingReceiveItemService')->destroy($deleteItems);
  304. app('LogService')->log(__METHOD__,"重新匹配ASN-删除原有ASN生成数据",json_encode($updateItems));
  305. }
  306. if (count($skus) > 0){
  307. $skuArr = array_keys($skus);
  308. /** @var CommodityService $commodityService */
  309. $commodityService = app('CommodityService');
  310. $commodities = $commodityService->get(['owner_id'=>$storeCheckingReceive->owner ? $storeCheckingReceive->owner->id : null,'sku'=>$skuArr]);
  311. $createItems = [];
  312. foreach ($commodities as $commodity){
  313. $createItems[] = [
  314. 'store_checking_receive_id' => $storeCheckingReceive->id,
  315. 'commodity_id' => $commodity->id,
  316. 'imported_amount' => 0,
  317. 'counted_amount' => 0,
  318. 'asn_amount' => $skus[$commodity->sku],
  319. 'imported_diff_amount' => 0,
  320. 'asn_diff_amount' => $skus[$commodity->sku],
  321. ];
  322. $diffAmount += $skus[$commodity->sku];
  323. }
  324. if (count($createItems) > 0)app('StoreCheckingReceiveItemService')->insert($createItems);
  325. }
  326. $data = app('StoreCheckingReceiveService')->updateFind($storeCheckingReceive,[
  327. 'asn'=>$asn,'is_asn_diff'=>$diffAmount===0 ? "否" : "是",'status'=>'已ASN入库'
  328. ]);
  329. app('LogService')->log(__METHOD__,"修改盘收任务",json_encode($data,JSON_UNESCAPED_UNICODE));
  330. return ['success'=>true, 'data'=>$data];
  331. }
  332. public function receipt(Request $request){
  333. if(!Gate::allows('入库管理-快速入库-录入')){ return redirect(url('/')); }
  334. $id = $request->id ?? false;
  335. /** @var StoreCheckingReceiveService $storeCheckingReceiveService */
  336. $storeCheckingReceiveService = app('StoreCheckingReceiveService');
  337. /** @var StoreCheckingReceive $storeCheckingReceive */
  338. $storeCheckingReceive = $storeCheckingReceiveService->find($id);
  339. if (!$storeCheckingReceive)return ['success'=>false, 'data'=>'盘收任务不存在'];
  340. if ($storeCheckingReceive->status == '已收货')return ['success'=>false, 'data'=>'盘收任务已结束'];
  341. $storeController = new StoreController();
  342. $result = $storeController->quickStorage($storeCheckingReceive->asn,"正品",null,false);
  343. if ($result['success']) $data = $storeCheckingReceiveService->updateFind($storeCheckingReceive,['status'=>"已收货"]);
  344. else{
  345. $data = $storeCheckingReceiveService->updateFind($storeCheckingReceive,['status'=>"收货失败"]);
  346. app('LogService')->log(__METHOD__,"盘收快速收货失败",json_encode($result['data'],JSON_UNESCAPED_UNICODE)." | ".json_encode($data,JSON_UNESCAPED_UNICODE));
  347. }
  348. return ['success'=>true, 'data'=>$data];
  349. }
  350. //修改实盘数量
  351. public function updateCountedAmount(Request $request){
  352. if(!Gate::allows('入库管理-盘收一体-盘收-编辑')){ return ['success'=>false, 'data'=>'无权操作!']; }
  353. $id = $request->id ?? null;
  354. $counted_amount = $request->counted_amount ?? null;
  355. if (!$id)return ['success'=>false, 'data'=>'参数传递错误!'];
  356. $item = app('StoreCheckingReceiveItemService')->find($id);
  357. if (!$item)return ['success'=>false, 'data'=>'被盘项不存在'];
  358. $params = ["counted_amount"=>$counted_amount];
  359. $data = [];
  360. if ($item->imported_amount){
  361. $params["imported_diff_amount"] = (int)$counted_amount - (int)$item->imported_amount;
  362. $data["imported_diff_amount"] = $params["imported_diff_amount"];
  363. }
  364. if ($item->asn_amount){
  365. $params["asn_diff_amount"] = (int)$counted_amount - (int)$item->asn_diff_amount;
  366. $data["asn_diff_amount"] = $params["asn_diff_amount"];
  367. }
  368. //修改差异状态
  369. if ($item->imported_amount || $item->asn_amount){
  370. $withs = ['storeCheckingReceiveItems'];
  371. $storeCheckingReceive = app('StoreCheckingReceiveService')->find($item->store_checking_receive_id,$withs);
  372. if ($storeCheckingReceive)$this->updateDiffStatus($storeCheckingReceive);
  373. }
  374. app('StoreCheckingReceiveItemService')->updateFind($item,$params);
  375. app('LogService')->log(__METHOD__,"盘点修改实盘数",'item:'.json_encode($item)."update:",$counted_amount);
  376. return ['success'=>true,"data"=>$data];
  377. }
  378. //修改差异状态
  379. private function updateDiffStatus(StoreCheckingReceive $scr){
  380. $items = $scr->storeCheckingReceiveItems ?? [];
  381. $is_receive_diff = "否";
  382. $is_asn_diff = "否";
  383. foreach ($items as $item){
  384. if ($item->imported_diff_amount)$is_receive_diff = "是";
  385. if ($item->asn_diff_amount)$is_asn_diff = "是";
  386. }
  387. $update = [];
  388. if ($scr->is_receive_diff != $is_receive_diff){
  389. $update["is_receive_diff"] = $is_receive_diff;
  390. }
  391. if ($scr->is_asn_diff != $is_asn_diff){
  392. $update["is_asn_diff"] = $is_asn_diff;
  393. }
  394. if (count($update) > 0){
  395. $scr->update($update);
  396. app('LogService')->log(__METHOD__,"修改差异状态",json_encode($scr,JSON_UNESCAPED_UNICODE));
  397. }
  398. }
  399. public function destroyItem(Request $request)
  400. {
  401. if (app("StoreCheckingReceiveItemService")->destroy($request->input("id")))return ["success"=>true];
  402. return ["success"=>false,"data"=>"删除失败"];
  403. }
  404. }