Procházet zdrojové kódy

入库管理-盘收一体
需执行迁移

Zhouzhendong před 5 roky
rodič
revize
1a40ba4ac7

+ 1 - 0
app/Http/Controllers/CommodityController.php

@@ -205,6 +205,7 @@ class CommodityController extends Controller
         $commoditiesId = [];
         $barcodes = [];
         foreach ($commodities as $commodity){
+            if (!isset($map[$commodity->sku]))continue;
             $wms = $wmsCommodities[$map[$commodity->sku]];
             $trimSku = rtrim($wms->sku,"*");
             if (($commodity->sku != $trimSku) || ($commodity->length != $wms->skulength)

+ 248 - 13
app/Http/Controllers/StoreCheckingReceiveController.php

@@ -3,14 +3,22 @@
 namespace App\Http\Controllers;
 
 use App\Imports\StoreCheckingReceiveImport;
+use App\Services\CommodityService;
+use App\Services\LogService;
+use App\Services\OracleDocAsnDetailService;
 use App\Services\StoreCheckingReceiveService;
+use App\StoreCheckingReceive;
+use Exception;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Cache;
+use Illuminate\Support\Facades\Gate;
+use Illuminate\Support\Facades\Http;
 use Maatwebsite\Excel\Facades\Excel;
 
 class StoreCheckingReceiveController extends Controller
 {
     public function mission(Request $request){
+        if(!Gate::allows('入库管理-盘收一体-盘收-查看')){ return redirect(url('/'));  }
         /** @var StoreCheckingReceiveService $service */
         $service = app('storeCheckingReceiveService');
 
@@ -21,6 +29,7 @@ class StoreCheckingReceiveController extends Controller
     }
 
     public function import(Request $request){
+        if(!Gate::allows('入库管理-盘收一体-盘收-编辑')){ return ['success'=>false, 'data'=>'无权操作!'];  }
         $fileSuffix=$request->file('file')->getClientOriginalExtension();
         if ($fileSuffix != 'xlsx' && $fileSuffix != 'xls' && $fileSuffix != 'csv')
             return ['success'=>false,'data'=>'不支持该文件类型'];
@@ -35,28 +44,34 @@ class StoreCheckingReceiveController extends Controller
         return ["success"=>false, "data"=>"读取导入文件错误"];
     }
 
-    public function show($id){
+    public function show($id,Request $request){
+        if(!Gate::allows('入库管理-盘收一体-盘收-查看')){ return redirect(url('/'));  }
         /** @var StoreCheckingReceiveService $service */
         $service = app('storeCheckingReceiveService');
         $storeCheckingReceive = $service->find($id);
+        $is_show = $request->is_show ?? true;
 
         if ($storeCheckingReceive->owner ?? false){
             $commodityController = new CommodityController();
             $commodityController->syncOwnerCommodities($storeCheckingReceive->owner->id, $storeCheckingReceive->owner->code);
         }
 
-        return view('store.checkingReceive.show',compact('storeCheckingReceive'));
+        return view('store.checkingReceive.show',compact('storeCheckingReceive','is_show'));
     }
 
     public function insertItem(Request $request){
+        if(!Gate::allows('入库管理-盘收一体-盘收-查看')){ return ['success'=>false, 'data'=>'无权操作!'];  }
         $mission_id = $request->mission_id ?? false;
         $goods = $request->goods ?? false;
+        if (!($goods["amount"] ?? false))$goods["amount"] = 1;
         if (!$mission_id || !$goods)return ['success'=>false, 'data'=>'参数传递错误!'];
         $storeCheckingReceive = app('storeCheckingReceiveService')->find($mission_id);
         if (!$storeCheckingReceive)return ['success'=>false, 'data'=>'盘收任务不存在'];
 
-        $item_id = null;
-        $item_amount = null;
+        $storeCheckingReceiveItem = null;
+        $is_receive_diff = "否";
+        $is_asn_diff = "否";
+        $is_inventory_complete = true;
         foreach ($storeCheckingReceive->storeCheckingReceiveItems as $item){
             if (!$item->commodity)continue;
             if (count($item->commodity->barcodes) < 1)continue;
@@ -66,19 +81,53 @@ class StoreCheckingReceiveController extends Controller
                         $goods['batch_number'] == $item->batch_code &&
                         $goods['produce_date'] == $item->produce_date &&
                         $goods['valid_date'] == $item->valid_date){
-                        $item_id = $item->id;
-                        $item_amount = $item->amount;
+                        $storeCheckingReceiveItem = $item;
                         break;
                     }
                 }
             }
+            if ($storeCheckingReceiveItem)continue;
+            if ($item->imported_diff_amount > 0)$is_receive_diff = "是";
+            if (!$item->counted_amount)$is_inventory_complete = false;
         }
 
-        if ($item_id){
-            $item = app('storeCheckingReceiveItemService')->update(['id'=>$item_id],['amount'=>($item_amount+$goods['amount'])]);
-            $item->load(['commodity'=>function($query){
-                $query->with('barcodes');
-            }]);
+        if ($storeCheckingReceiveItem){
+            $counted_amount = $storeCheckingReceiveItem->counted_amount+$goods['amount'];
+            $params = ['counted_amount'=>$counted_amount];
+            if (!$storeCheckingReceiveItem->imported_amount){
+                $params['imported_amount'] = 0;
+                $params['imported_diff_amount'] = $counted_amount;
+            }else $params['imported_diff_amount'] = abs($counted_amount-$storeCheckingReceiveItem->imported_amount);
+            if ($storeCheckingReceiveItem->asn_amount)$params['asn_diff_amount'] = abs($counted_amount-$storeCheckingReceiveItem->asn_amount);
+
+            if (isset($params['imported_diff_amount']) && $params['imported_diff_amount'] > 0)$is_receive_diff = "是";
+            if (isset($params['asn_diff_amount']) && $params['asn_diff_amount'] > 0)$is_asn_diff = "是";
+            $item = app('storeCheckingReceiveItemService')->updateFind($storeCheckingReceiveItem,$params);
+            LogService::log(__METHOD__,"清点数量",json_encode($item,JSON_UNESCAPED_UNICODE));
+
+            switch ($storeCheckingReceive->status){
+                case '已导入':
+                    $SCR = app('storeCheckingReceiveService')->updateFind($storeCheckingReceive,['status'=>'清点中']);
+                    LogService::log(__METHOD__,"修改盘收任务状态为清点中",json_encode($SCR,JSON_UNESCAPED_UNICODE));
+                    break;
+                case '清点中':
+                    $res = [];
+                    if ($is_inventory_complete){
+                        $res['status']='已清点';
+                    }
+                    //差异存在时 判断差异是否变化,变化则更新,差异不存在时 判断差异是否存在 存在则更新
+                    if (($storeCheckingReceive->is_receive_diff && $storeCheckingReceive->is_receive_diff != $is_receive_diff)
+                        || (!$storeCheckingReceive->is_receive_diff && isset($params['imported_diff_amount'])))
+                        $res['is_receive_diff'] = $is_receive_diff;
+                    if (($storeCheckingReceive->is_asn_diff && $storeCheckingReceive->is_asn_diff != $is_asn_diff)
+                        || (!$storeCheckingReceive->is_asn_diff && isset($params['asn_diff_amount'])))
+                        $res['is_receive_diff'] = $is_receive_diff;
+                    if (count($res) > 0){
+                        $SCR = app('storeCheckingReceiveService')->updateFind($storeCheckingReceive,$res);
+                        LogService::log(__METHOD__,"修改盘收任务",json_encode($SCR,JSON_UNESCAPED_UNICODE));
+                    }
+                    break;
+            }
             return ['success'=>true, 'type'=>"update", 'data'=>$item];
         }
         $commodity_barcode = app('commodityBarcodeService')->first([
@@ -89,13 +138,199 @@ class StoreCheckingReceiveController extends Controller
             'store_checking_receive_id' => $mission_id,
             'bin_number' => $goods['bin_number'],
             'commodity_id' => $commodity_barcode->commodity_id,
-            'produced_at' => $goods['produced_at'],
-            'invalid_at' => $goods['invalid_at'],
+            'imported_amount' => 0,
+            'imported_diff_amount' => $goods['amount'],
+            'produced_at' => $goods['produce_date'],
+            'invalid_at' => $goods['valid_date'],
             'batch_code' => $goods['batch_number'],
+            'counted_amount' => $goods['amount'],
         ]);
         $item->load(['commodity'=>function($query){
             $query->with('barcodes');
         }]);
+        switch ($storeCheckingReceive->status){
+            case '已导入':
+                $SCR = app('storeCheckingReceiveService')->updateFind($storeCheckingReceive,['status'=>'清点中']);
+                LogService::log(__METHOD__,"修改盘收任务状态为清点中",json_encode($SCR,JSON_UNESCAPED_UNICODE));
+                break;
+            case '清点中':
+                $res = [];
+                if ($is_inventory_complete){
+                    $res['status']='已清点';
+                }
+                //差异存在时 判断差异是否变化,变化则更新,差异不存在时 判断差异是否存在 存在则更新
+                if ($is_receive_diff == "否")$is_receive_diff = $item->imported_diff_amount>0 ? "是" : "否";
+                if ($storeCheckingReceive->is_receive_diff != $is_receive_diff)
+                    $res['is_receive_diff'] = $is_receive_diff;
+                if ($storeCheckingReceive->is_asn_diff && ($storeCheckingReceive->is_asn_diff != $is_asn_diff))
+                    $res['is_receive_diff'] = $is_receive_diff;
+                if (count($res) > 0){
+                    $SCR = app('storeCheckingReceiveService')->updateFind($storeCheckingReceive,$res);
+                    LogService::log(__METHOD__,"修改盘收任务",json_encode($SCR,JSON_UNESCAPED_UNICODE));
+                }
+                break;
+        }
         return ['success'=>true, 'type'=>'create', 'data'=>$item];
     }
+
+    public function export(Request $request){
+        if(!Gate::allows('入库管理-盘收一体-盘收-查看')){ return redirect(url('/'));  }
+        $id = $request->mission_id ?? false;
+        $storeCheckingReceive = app('storeCheckingReceiveService')->find($id);
+
+        if (!$storeCheckingReceive) new \Exception('盘收任务不存在');
+
+        $row = ['ID','格口号','商品名','商品条码','导入数量','实盘数量','ASN数量','导入差异数','ASN差异数','生产日期','有效日期','批次号','唯一码'];
+        $list = [];
+        foreach ($storeCheckingReceive->storeCheckingReceiveItems as $item){
+            $code = '';
+            foreach ($item->commodity ? $item->commodity->barcodes : [] as $barcode){
+                $code .= $barcode->code;
+            }
+            $list[] = [
+                $item->id,
+                $item->bin_number,
+                $item->commodity ? $item->commodity->name : '',
+                $code,
+                $item->imported_amount,
+                $item->counted_amount,
+                $item->asn_amount,
+                $item->imported_diff_amount,
+                $item->asn_diff_amount,
+                $item->produced_at,
+                $item->invalid_at,
+                $item->batch_code,
+                $item->unique_code,
+            ];
+        }
+        $post = Http::post(config('go.export.url'),['type'=>'base','data'=>json_encode([
+            'row'=>$row,'list'=>$list
+        ],JSON_UNESCAPED_UNICODE)]);
+        if ($post->status() == 500){
+            throw new Exception($post->header("Msg"));
+        }
+        return response($post,200, [
+            "Content-type"=>"application/octet-stream",
+            "Content-Disposition"=>"attachment; filename=盘收任务详情-".date('ymdHis').'.xlsx',
+        ]);
+    }
+
+    public function resetAmount(Request $request){
+        if(!Gate::allows('入库管理-盘收一体-盘收-编辑')){ return ['success'=>false, 'data'=>'无权操作!'];  }
+        $id = $request->mission_id ?? false;
+        if (!$id) new \Exception('盘收任务不存在');
+
+        app('storeCheckingReceiveItemService')->update(['store_checking_receive_id'=>$id],[
+            'counted_amount'=>0,
+            'imported_diff_amount'=>null,
+            'asn_diff_amount'=>null,
+        ]);
+        LogService::log(__METHOD__,"重置盘收任务所有数量","store_checking_receive_id:".$id);
+        return ['success'=>true];
+    }
+
+    public function matchASN(Request $request){
+        if(!Gate::allows('入库管理-快速入库-录入')){ return ['success'=>false, 'data'=>'无权操作!'];  }
+        $asn = $request->asn ?? false;
+        $id = $request->mission_id ?? false;
+        if (!$asn || !$id)return ['success'=>false, 'data'=>'传递参数错误'];
+
+        $storeCheckingReceive = app('storeCheckingReceiveService')->find($id);
+        if (!$storeCheckingReceive) return ['success'=>false, 'data'=>'未找到此盘点任务!'];
+
+        /** @var OracleDocAsnDetailService $oracleDocAsnDetailService */
+        $oracleDocAsnDetailService = app('oracleDocAsnDetailService');
+        $docAsnDetails = $oracleDocAsnDetailService->get([
+            'asnno'=>$asn,
+            'customerid'=>$storeCheckingReceive->owner ? $storeCheckingReceive->owner->code : null],[
+                'asnno','customerid','asnlineno','sku','expectedqty'
+        ]);
+        if (count($docAsnDetails) < 1) return ['success'=>false, 'data'=>'该货主下此ASN号不存在'];
+
+        $diffAmount = 0;
+        $skus = [];
+        foreach ($docAsnDetails as $detail){
+            if ($skus[$detail->sku] ?? false) $skus[$detail->sku] += $detail->expectedqty;
+            else $skus[$detail->sku] = $detail->expectedqty;
+        }
+        $deleteItems = [];
+        $updateItems = [];
+        $updateItems[] = ['id','asn_amount','asn_diff_amount'];
+        foreach ($storeCheckingReceive->storeCheckingReceiveItems as $item){
+            if (!($item->commodity ? $item->commodity->sku : null))continue;
+            if ($storeCheckingReceive->asn && ($item->asn_amount != null)
+                && (!($item->counted_amount ?? false))){
+                $deleteItems[] = $item->id;
+                continue;
+            }
+            if ($skus[$item->commodity->sku] ?? false){
+                $asn_diff_amount = abs($skus[$item->commodity->sku] - $item->counted_amount);
+                $updateItems[] = [
+                    'id'=>$item->id,
+                    'asn_amount'=>$skus[$item->commodity->sku],
+                    'asn_diff_amount'=>$asn_diff_amount,
+                ];
+                $item->asn_diff_amount = $asn_diff_amount;
+                unset($skus[$item->commodity->sku]);
+            }
+            $diffAmount += $item->asn_diff_amount;
+        }
+        if (count($updateItems) > 0){
+            app('storeCheckingReceiveItemService')->batchUpdate($updateItems);
+            LogService::log(__METHOD__,"匹配ASN-批量更新ASN数量",json_encode($updateItems));
+        }
+
+        if (count($deleteItems) > 0){
+            app('storeCheckingReceiveItemService')->destroy($deleteItems);
+            LogService::log(__METHOD__,"重新匹配ASN-删除原有ASN生成数据",json_encode($updateItems));
+        }
+
+
+        if (count($skus) > 0){
+            $skuArr = array_keys($skus);
+            /** @var CommodityService $commodityService */
+            $commodityService = app('commodityService');
+            $commodities = $commodityService->get(['owner_id'=>$storeCheckingReceive->owner ? $storeCheckingReceive->owner->id : null,'sku'=>$skuArr]);
+            $createItems = [];
+            foreach ($commodities as $commodity){
+                $createItems[] = [
+                    'store_checking_receive_id' => $storeCheckingReceive->id,
+                    'commodity_id' => $commodity->id,
+                    'imported_amount' => 0,
+                    'counted_amount' => 0,
+                    'asn_amount' => $skus[$commodity->sku],
+                    'imported_diff_amount' => 0,
+                    'asn_diff_amount' => $skus[$commodity->sku],
+                ];
+                $diffAmount += $skus[$commodity->sku];
+            }
+
+            if (count($createItems) > 0)app('storeCheckingReceiveItemService')->insert($createItems);
+        }
+        $data = app('storeCheckingReceiveService')->updateFind($storeCheckingReceive,[
+            'asn'=>$asn,'is_asn_diff'=>$diffAmount==0 ? "否" : "是",'status'=>'已ASN入库'
+        ]);
+        LogService::log(__METHOD__,"修改盘收任务",json_encode($data,JSON_UNESCAPED_UNICODE));
+        return ['success'=>true, 'data'=>$data];
+    }
+
+    public function receipt(Request $request){
+        if(!Gate::allows('入库管理-快速入库-录入')){ return redirect(url('/'));  }
+        $id = $request->id ?? false;
+
+        /** @var StoreCheckingReceiveService $storeCheckingReceiveService */
+        $storeCheckingReceiveService = app('storeCheckingReceiveService');
+        /** @var StoreCheckingReceive $storeCheckingReceive */
+        $storeCheckingReceive = $storeCheckingReceiveService->find($id);
+        if (!$storeCheckingReceive)return ['success'=>false, 'data'=>'盘收任务不存在'];
+
+        $storeController = new StoreController();
+        $result = $storeController->quickStorage($storeCheckingReceive->asn,"正品",null);
+        if ($result['success']) $data = $storeCheckingReceiveService->updateFind($storeCheckingReceive,['status'=>"已收货"]);
+        else{
+            $data = $storeCheckingReceiveService->updateFind($storeCheckingReceive,['status'=>"收货失败"]);
+            LogService::log(__METHOD__,"盘收快速收货失败",json_encode($result['data'],JSON_UNESCAPED_UNICODE)." | ".json_encode($data,JSON_UNESCAPED_UNICODE));
+        }
+        return ['success'=>true, 'data'=>$data];
+    }
 }

+ 25 - 62
app/Http/Controllers/StoreController.php

@@ -54,9 +54,16 @@ class StoreController extends Controller
     {
         if(!Gate::allows('入库管理-快速入库-录入')){ return redirect(url('/'));  }
         $this->validator($request);
-        $WMSReflectReceive=WMSReflectReceive::with('skus')->where('ASNNO',$request->input('asn_code'))->first();
-        if (!$WMSReflectReceive)return redirect('store/fast/create')->with('successError','ASN编号不存在!');
-        $warehouse=Warehouse::where('code',$WMSReflectReceive->WAREHOUSEID)->first();
+        $result = $this->quickStorage($request->input('asn_code'),$request->input('quality'),$request->input('depository_code'));
+        $response = redirect('store/fast/create');
+        if ($result['success'])return redirect('store/fast/create')->with('successTip',$result['data']);
+        else return $response->with('successError',$result['data']);
+    }
+
+    public function quickStorage($asn,$quality,$depository_code){
+        $WMSReflectReceive=WMSReflectReceive::with('skus')->where('ASNNO',$asn)->first();
+        if (!$WMSReflectReceive)return ['success'=>false, 'data'=>"ASN编号不存在!"];
+        $warehouse=Warehouse::query()->where('code',$WMSReflectReceive->WAREHOUSEID)->first();
         if (!$warehouse&&$WMSReflectReceive->WAREHOUSEID){
             $warehouse=new Warehouse([
                 'name'=>$WMSReflectReceive->WAREHOUSEID,
@@ -64,7 +71,7 @@ class StoreController extends Controller
             ]);
             $warehouse->save();
         }
-        $owner=Owner::where('code',$WMSReflectReceive->CUSTOMERID)->first();
+        $owner=Owner::query()->where('code',$WMSReflectReceive->CUSTOMERID)->first();
         if (!$owner&&$WMSReflectReceive->CUSTOMERID){
             $owner=new Warehouse([
                 'name'=>$WMSReflectReceive->CUSTOMERID,
@@ -72,7 +79,7 @@ class StoreController extends Controller
             ]);
             $owner->save();
         }
-        $store=Store::where('asn_code',$WMSReflectReceive->ASNNO)->first();
+        $store=Store::query()->where('asn_code',$WMSReflectReceive->ASNNO)->first();
         if(!$store){
             $store=new Store([
                 'asn_code'=>$WMSReflectReceive->ASNNO,
@@ -84,13 +91,13 @@ class StoreController extends Controller
             ]);
             $store->save();
 
-            $customDepository=(function()use($request){
-                $customDepository=Depository::where('code',$request->input('depository_code'))->first();
-                if($request->input('depository_code')){
+            $customDepository=(function()use($depository_code){
+                $customDepository=Depository::query()->where('code',$depository_code)->first();
+                if($depository_code){
                     if (!$customDepository){
                         $depository=new Depository([
-                            'name'=>$request->input('depository_code'),
-                            'code'=>$request->input('depository_code')
+                            'name'=>$depository_code,
+                            'code'=>$depository_code
                         ]);
                         $depository->save();
                     }
@@ -102,7 +109,7 @@ class StoreController extends Controller
                 foreach ($WMSReflectReceive->skus as $sku){
                     $depository=(function()use($sku,$customDepository){
                         if($customDepository)return $customDepository;
-                        $depository=Depository::where('code',$sku->LOTATT05)->first();
+                        $depository=Depository::query()->where('code',$sku->LOTATT05)->first();
                         if (!$depository){
                             if (!$sku->LOTATT05)return $depository;
                             $depository=new Depository([
@@ -119,7 +126,7 @@ class StoreController extends Controller
                         'name'=>$sku->SKUDESCRC,
                         'sku'=>$sku->SKU,
                         'barcode'=>$sku->ALTERNATE_SKU1,
-                        'quality'=>$request->input('quality'),
+                        'quality'=>$quality,
                         'status'=>'未入库',
                     ]);
                     if ($depository)$storeItem->depository_id=$depository->id;
@@ -127,73 +134,29 @@ class StoreController extends Controller
                 }
             }
         }
-        $store=Store::with('storeItems')->where('asn_code',$request->input('asn_code'))->first();
+        /** @var Store $store */
+        $store=Store::with('storeItems')->where('asn_code',$asn)->first();
         $storeApi=new FStoreController();
         $result=$storeApi->accomplishToWMS($store,[
-            'quality'=>$request->input('quality'),
-            'depository_code'=>$request->input('depository_code'),
+            'quality'=>$quality,
+            'depository_code'=>$depository_code,
             'follow_code'=>$store['id'],
         ]);
         if ($result){
             $store->status='已入库';
             $store->save();
             if ($store->storeItems){
-                $quality=$request->input('quality');
                 $store->storeItems->each(function ($storeItem)use($quality){
                     $storeItem->status='已入库';
                     $storeItem->quality=$quality;
                     $storeItem->save();
                 });
             }
-            return redirect('store/fast/create')->with('successTip','成功!');
+            return ['success'=>true, 'data'=>"成功!"];
         }
-        return redirect('store/fast/create')->with('successError','失败!请检查错误日志');
-    }
-
-    /**
-     * Display the specified resource.
-     *
-     * @param  \App\Store  $store
-     * @return Response
-     */
-    public function show(Store $store)
-    {
-        //
-    }
-
-    /**
-     * Show the form for editing the specified resource.
-     *
-     * @param  \App\Store  $store
-     * @return Response
-     */
-    public function edit(Store $store)
-    {
-        //
+        return ['success'=>false, 'data'=>"失败!请检查错误日志"];
     }
 
-    /**
-     * Update the specified resource in storage.
-     *
-     * @param Request $request
-     * @param  \App\Store  $store
-     * @return Response
-     */
-    public function update(Request $request, Store $store)
-    {
-        //
-    }
-
-    /**
-     * Remove the specified resource from storage.
-     *
-     * @param  \App\Store  $store
-     * @return Response
-     */
-    public function destroy(Store $store)
-    {
-        //
-    }
 
     public function validator(Request $request){
         $validator=Validator::make($request->input(),[

+ 3 - 2
app/Http/Controllers/TestController.php

@@ -390,8 +390,9 @@ class TestController extends Controller
     }
 
     public function test2(){
-        $a = "025648*96875**";
-        dd(substr($a,-1));
+        $skus = ["a"=>1,"b"=>2,"c"=>3];
+        $skuArr = array_keys($skus);
+        dd($skuArr);
     }
 
     /*1*/

+ 11 - 2
app/Imports/StoreCheckingReceiveImport.php

@@ -3,6 +3,7 @@
 namespace App\Imports;
 
 use App\Services\CommodityService;
+use App\Services\LogService;
 use Carbon\Carbon;
 use Illuminate\Support\Collection;
 use Illuminate\Support\Facades\Cache;
@@ -190,7 +191,10 @@ class StoreCheckingReceiveImport implements ToCollection,WithHeadingRow
             ]);
             array_push($skuParam, $sku);
         }
-        if (count($commodities) > 0)$commodityService->insert($commodities);
+        if (count($commodities) > 0){
+            $commodityService->insert($commodities);
+            LogService::log(__METHOD__,"导入盘收任务-批量录入商品",json_encode($commodities,JSON_UNESCAPED_UNICODE));
+        }
         if (count($skuParam) > 0)$commodities = $commodityService->get(["owner_id"=>$owner->id,"sku"=>$skuParam]);
         foreach ($commodities as $commodity){
             foreach ($skus[$commodity->sku] as $i => $index){
@@ -209,7 +213,10 @@ class StoreCheckingReceiveImport implements ToCollection,WithHeadingRow
             }
             unset($skus[$commodity->sku]);
         }
-        if (count($barcodes) > 0) app('commodityBarcodeService')->insert($barcodes);
+        if (count($barcodes) > 0){
+            app('commodityBarcodeService')->insert($barcodes);
+            LogService::log(__METHOD__,"导入盘收任务-批量录入商品条码",json_encode($barcodes,JSON_UNESCAPED_UNICODE));
+        }
 
         if (count($items) < 1){
             Cache::put("storeCheckingReceive",["success"=>false, "errors"=>$errors],86400);
@@ -220,6 +227,7 @@ class StoreCheckingReceiveImport implements ToCollection,WithHeadingRow
             "created_at" => date('Y-m-d H:i:s'),
             'status' => "已导入",
         ]);
+        LogService::log(__METHOD__,"导入盘收任务-录入盘收任务",json_encode($storeCheckingReceive,JSON_UNESCAPED_UNICODE));
         $storeCheckingReceive->owner_name = $owner_name;
 
         foreach ($items as &$item){
@@ -227,6 +235,7 @@ class StoreCheckingReceiveImport implements ToCollection,WithHeadingRow
         }
 
         app('storeCheckingReceiveItemService')->insert($items);
+        LogService::log(__METHOD__,"导入盘收任务-批量录入盘收记录",json_encode($items,JSON_UNESCAPED_UNICODE));
 
         Cache::put("storeCheckingReceive",["success"=>true,"data"=>$storeCheckingReceive,"errors"=>$errors],86400);
         return true;

+ 2 - 0
app/Providers/AppServiceProvider.php

@@ -7,6 +7,7 @@ use App\Services\CommodityBarcodeService;
 use App\Services\CommodityService;
 use App\Services\InventoryCompareService;
 use App\Services\OracleBasSkuService;
+use App\Services\OracleDocAsnDetailService;
 use App\Services\OracleDOCOrderHeaderService;
 use App\Services\OrderIssuePerformanceService;
 use App\OracleActAllocationDetail;
@@ -106,5 +107,6 @@ class AppServiceProvider extends ServiceProvider
         app()->singleton('commodityBarcodeService',CommodityBarcodeService::class);
         app()->singleton('commodityService',CommodityService::class);
         app()->singleton('oracleBasSkuService',OracleBasSkuService::class);
+        app()->singleton('oracleDocAsnDetailService',OracleDocAsnDetailService::class);
     }
 }

+ 40 - 0
app/Services/OracleDocAsnDetailService.php

@@ -0,0 +1,40 @@
+<?php 
+
+namespace App\Services; 
+
+use App\OracleDOCASNDetail;
+
+Class OracleDocAsnDetailService
+{
+    const TABLE = "DOC_ASN_DETAILS";
+    public function getLeftJoinBasSku(array $params){
+        $query = OracleDOCASNDetail::query();
+        foreach ($params as $column => $value){
+            if (is_array($value)){
+                $query->whereIn(self::TABLE.'.'.$column,$value);
+            }
+            $query->where(self::TABLE.'.'.$column,$value);
+        }
+        $query->selectRaw(self::TABLE.".asnno,".self::TABLE.".asnlineno,"
+            .self::TABLE.".customerid,".self::TABLE.".sku,".self::TABLE.".expectedqty");
+        $query->join('BAS_SKU',function ($join){
+            $join->on(self::TABLE.".sku",'=','BAS_SKU.sku')
+                ->on(self::TABLE.".customerid",'=',"BAS_SKU.customerid");
+        },null,null,'left');
+        $query->selectRaw('BAS_SKU.alternate_sku1,BAS_SKU.alternate_sku2');
+        return $query->get();
+    }
+
+    public function get(array $params, $column = null){
+        $query = OracleDOCASNDetail::query();
+        if ($column)$query->select($column);
+        foreach ($params as $column => $value){
+            if (is_array($value)){
+                $query->whereIn($column,$value);
+            }
+            $query->where($column,$value);
+        }
+        return $query->get();
+    }
+
+}

+ 23 - 4
app/Services/StoreCheckingReceiveItemService.php

@@ -2,6 +2,7 @@
 
 namespace App\Services; 
 
+use App\Services\common\BatchUpdateService;
 use App\StoreCheckingReceiveItem;
 
 Class StoreCheckingReceiveItemService
@@ -10,15 +11,33 @@ Class StoreCheckingReceiveItemService
         return StoreCheckingReceiveItem::query()->insert($params);
     }
 
+    public function updateFind(StoreCheckingReceiveItem $item, array $values){
+        $item->update($values);
+        $item->load(['commodity'=>function($query){
+            $query->with('barcodes');
+        }]);
+        return $item;
+    }
+
+    public function create(array $params){
+        return StoreCheckingReceiveItem::query()->create($params);
+    }
+
     public function update(array $params, array $values){
         $query = StoreCheckingReceiveItem::query();
-        foreach ($params as $column => $value){
-            $query->where($column,$value);
+        foreach ($params as $column => $param){
+            if (is_array($param))$query->whereIn($column,$param);
+            else $query->where($column,$param);
         }
         return $query->update($values);
     }
 
-    public function create(array $params){
-        return StoreCheckingReceiveItem::query()->create($params);
+    public function batchUpdate(array $params){
+        return app(BatchUpdateService::class)->batchUpdate('store_checking_receive_items', $params);
     }
+
+    public function destroy($id){
+        return StoreCheckingReceiveItem::destroy($id);
+    }
+
 }

+ 5 - 0
app/Services/StoreCheckingReceiveService.php

@@ -42,4 +42,9 @@ Class StoreCheckingReceiveService
             }]);
         }])->find($id);
     }
+
+    public function updateFind(StoreCheckingReceive $storeCheckingReceive, array $params){
+        $storeCheckingReceive->update($params);
+        return $storeCheckingReceive;
+    }
 }

+ 3 - 1
database/migrations/2020_09_15_141310_create_store_checking_receives_table.php

@@ -12,6 +12,8 @@ class CreateStoreCheckingReceivesTable extends Migration
         "入库管理-盘收一体",
         "入库管理-盘收一体-任务",
         "入库管理-盘收一体-盘收",
+        "入库管理-盘收一体-盘收-查看",
+        "入库管理-盘收一体-盘收-编辑",
     ];
     /**
      * Run the migrations.
@@ -24,7 +26,7 @@ class CreateStoreCheckingReceivesTable extends Migration
             $table->id();
             $table->bigInteger('owner_id')->index()->comment('外键货主');
             $table->timestamp('created_at')->index()->comment('创建时间');
-            $table->enum('status',['已导入','清点中','已清点','已入库'])->default('已导入')->comment('状态');
+            $table->enum('status',['已导入','清点中','已清点','已ASN入库','已收货','收货失败'])->default('已导入')->comment('状态');
             $table->enum('is_receive_diff',['是','否'])->nullable()->comment('接收差异');
             $table->string('asn')->nullable()->comment('asn单号');
             $table->enum('is_asn_diff',['是','否'])->nullable()->comment('ASN差异');

+ 16 - 0
resources/views/store/checkingReceive/_modal.blade.php

@@ -0,0 +1,16 @@
+<div class="modal fade" id="asnWindow" tabindex="-1" role="dialog" aria-hidden="true">
+    <div class="modal-dialog modal-dialog-centered modal-lg" role="document">
+        <div class="modal-content">
+            <div class="modal-body" style="text-align:center;height: 150px">
+                <div class="mt-5">
+                    <label class="w-75 h-25">
+                        <input class="form-control form-control-sm" v-model="asn" placeholder="输入ASN号">
+                    </label>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button class="col-12 btn btn-success" @click="matchASN()">开始匹配</button>
+            </div>
+        </div>
+    </div>
+</div>

+ 70 - 3
resources/views/store/checkingReceive/mission.blade.php

@@ -7,6 +7,8 @@
     @component('store.checkingReceive.menu')@endcomponent
 </span>
 <div id="container" class="d-none container-fluid">
+    @include('store.checkingReceive._modal')
+
     <div class="modal fade" id="import" tabindex="-1" role="dialog" aria-hidden="true">
         <div class="modal-dialog modal-dialog-centered modal-lg" role="document">
             <div class="modal-content">
@@ -50,15 +52,26 @@
             <td>@{{ i+1 }}</td>
             <td>@{{ storeCheckingReceive.id }}</td>
             <td>@{{ storeCheckingReceive.owner_name }}</td>
-            <td>@{{ storeCheckingReceive.status }}</td>
+            <td class="font-weight-bold">@{{ storeCheckingReceive.status }}</td>
             <td>@{{ storeCheckingReceive.is_receive_diff }}</td>
             <td>@{{ storeCheckingReceive.asn }}</td>
             <td>@{{ storeCheckingReceive.is_asn_diff }}</td>
             <td>@{{ storeCheckingReceive.created_at }}</td>
             <td>
                 @can('入库管理-盘收一体-盘收')<a target="_blank" :href="'{{url('store/checkingReceive/mission')}}/'+storeCheckingReceive.id">
-                    <button class="btn btn-sm btn-outline-success">盘收</button>
+                    <button class="btn btn-sm btn-outline-dark">盘收</button>
                 </a>@endcan
+                <a target="_blank" :href="'{{url('store/checkingReceive/mission')}}/'+storeCheckingReceive.id+'?is_show=false'">
+                    <button class="btn btn-sm btn-outline-primary">查看</button>
+                </a>
+                @can('入库管理-盘收一体-盘收-编辑')
+                <button class="btn btn-sm btn-outline-success" data-toggle="modal" data-target="#asnWindow" @click="thisIndex=i">
+                    <span v-if="storeCheckingReceive.asn">重新</span>匹配ASN号
+                </button>@endcan
+                @can('入库管理-快速入库-录入')
+                <button v-if="storeCheckingReceive.status=='已ASN入库' && storeCheckingReceive.is_receive_diff != '是' && storeCheckingReceive.is_asn_diff != '是'"
+                        class="btn btn-sm btn-outline-info" @click="receipt(i)">快速入库</button>
+                @endcan
             </td>
         </tr>
     </table>
@@ -93,6 +106,8 @@
                     file : null,
                 },
                 popoverContent:'',
+                thisIndex : '',
+                asn : '',
             },
             mounted(){
                 $('#container').removeClass('d-none');
@@ -206,7 +221,59 @@
                 },
                 selectFile(){
                     $('#excelFile').trigger('click');
-                }
+                },
+                matchASN(){
+                    if (!this.asn){
+                        window.tempTip.setIndex(1099);
+                        window.tempTip.setDuration(3000);
+                        window.tempTip.show('请输入ASN号!');
+                        return;
+                    }
+                    let storeCheckingReceive = this.storeCheckingReceives[this.thisIndex];
+                    axios.post('{{url('store/checkingReceive/mission/matchASN')}}',{asn:this.asn,mission_id:storeCheckingReceive.id})
+                        .then(res=>{
+                            if (res.data.success){
+                                window.tempTip.setIndex(1099);
+                                window.tempTip.setDuration(2000);
+                                if (storeCheckingReceive.asn) window.tempTip.showSuccess("重新匹配ASN成功");
+                                else window.tempTip.showSuccess("匹配ASN成功");
+
+                                console.log(res.data.data);
+                                storeCheckingReceive.status = res.data.data.status;
+                                storeCheckingReceive.asn = res.data.data.asn;
+                                storeCheckingReceive.is_asn_diff = res.data.data.is_asn_diff;
+                                console.log(storeCheckingReceive);
+                                $("#asnWindow").modal('hide');
+                                return;
+                            }
+                            window.tempTip.setIndex(1099);
+                            window.tempTip.setDuration(3000);
+                            window.tempTip.show(res.data.data);
+                        }).catch(err=>{
+                        window.tempTip.setIndex(1099);
+                        window.tempTip.setDuration(3000);
+                        window.tempTip.show("网络错误:"+err);
+                    });
+                },
+                receipt(index){
+                    window.tempTip.confirm('是否要进行快速收货?',()=>{
+                        let storeCheckingReceive = this.storeCheckingReceives[index];
+                        axios.post('{{url('store/checkingReceive/mission/receipt')}}',{id:storeCheckingReceive.id})
+                            .then(res=>{
+                                if (res.data.success) {
+                                    window.tempTip.setDuration(2000);
+                                    window.tempTip.showSuccess("快速收货完成!");
+                                    storeCheckingReceive.status = res.data.data.status;
+                                    return;
+                                }
+                                window.tempTip.setDuration(3000);
+                                window.tempTip.show(res.data.data);
+                            }).catch(err=>{
+                            window.tempTip.setDuration(3000);
+                            window.tempTip.show("网络错误:"+err);
+                        })
+                    });
+                },
             },
         });
     </script>

+ 127 - 12
resources/views/store/checkingReceive/show.blade.php

@@ -12,7 +12,10 @@
     @endcomponent
 </span>
     <div id="container" class="d-none container-fluid">
-        <div class="row m-2 card">
+        @include('store.checkingReceive._modal')
+
+        @can('入库管理-盘收一体-盘收-编辑')
+        <div class="row m-2 card" v-if="is_show">
             <audio src="{{asset('sound/warning_otherBarcode.mp3')}}" controls="controls" preload id="soundWarning" hidden>
             </audio>
             <audio src="{{asset('sound/ding.mp3')}}" controls="controls" preload id="soundDing" hidden>
@@ -75,10 +78,11 @@
                 </div>
             </div>
         </div>
+        @endcan
         <div class="ml-2 mt-2">
-            <button class="btn btn-sm btn-outline-dark">导出</button>
-            <button class="btn btn-sm btn-outline-danger">重新清点</button>
-            <button class="btn btn-sm btn-outline-success">匹配ASN单据</button>
+            <button class="btn btn-sm btn-outline-dark" @click="exportItem()">导出</button>
+            @can('入库管理-盘收一体-盘收-编辑')<button class="btn btn-sm btn-outline-danger" @click="isResetAmount()">重新清点</button>@endcan
+            @can('入库管理-盘收一体-盘收-编辑')<button class="btn btn-sm btn-outline-success" data-toggle="modal" data-target="#asnWindow">匹配ASN单据</button>@endcan
         </div>
         <div class="row text-primary ml-1 mr-2 mt-1 mb-1 w-100" style="background-color: #c3e3b5">
             <span class="ml-1">任务ID: <b class="text-dark">@{{ storeCheckingReceive.id }}</b></span>
@@ -150,6 +154,8 @@
                 valid_date : '',
             },
             lastScannedBarcode : '',
+            asn : '',
+            is_show : {!! $is_show !!},
         },
         mounted(){
             $('#container').removeClass('d-none');
@@ -220,29 +226,58 @@
                 if(this.inputting.barcode && this.inputting.amount && this.inputting.bin_number){
                     if (this.status.commitButtonVisible){
                         this.commitGoods();
-                        this.status.commitButtonVisible=false;
                     }else this.status.commitButtonVisible=true;
                 }
             },
+            _isExist(item){
+                if (item.bin_number == this.inputting.bin_number
+                    && item.batch_code == this.inputting.batch_number
+                    && item.produced_at == this.inputting.produce_date
+                    && item.invalid_at == this.inputting.valid_date){
+                    return true;
+                }
+                return false;
+            },
             commitGoods: function () {
-                window.tempTip.setDuration(3500);
+                window.tempTip.setDuration(3000);
+                if (this.inputMode === 'regular'){
+                    if (!this.inputting.amount) {window.tempTip.show('请输入数量');return;}
+                    let item = this.getItem();
+                    if (item){
+                        if (item.produced_at && !this.inputting.produce_date){window.tempTip.show('请输入生产日期');return;}
+                        if (item.invalid_at && !this.inputting.valid_date){window.tempTip.show('请输入失效日期');return;}
+                        if (item.batch_code && !this.inputting.batch_number){window.tempTip.show('请输入批次号');return;}
+                        if (this._isExist(item)){
+                            if (!confirm('该单盘点已存在是否叠加数量?'))return;
+                        }
+                    }
+                }
                 if(!this.inputting.barcode){window.tempTip.show('请扫入条码');return;}
-                else if(!this.inputting.amount){window.tempTip.show('请输入数量');return;}
                 else if(!this.inputting.bin_number){window.tempTip.show('请输入隔口号');return;}
                 axios.post('{{url('store/checkingReceive/insertItem')}}',{mission_id : this.storeCheckingReceive.id,goods : this.inputting})
                     .then(res=>{
                         if (res.data.success) {
                             this.lastScannedBarcode = this.inputting.barcode;
-                            if (this.inputMode === 'regular')this.cleanInputs();
                             if (res.data.type === 'create'){
-                                console.log(res.data.data);
-                                this.storeCheckingReceiveItems.unshift(res.data.data);
+                                this._addStoreCheckingReceiveItem(res.data.data);
                                 window.tempTip.setDuration(2000);
                                 window.tempTip.showSuccess('成功提交:' + this.inputting.barcode);
                             }else{
-
+                                if (this.storeCheckingReceiveItems.length > 0 && res.data.data.id === this.storeCheckingReceiveItems[0].id){
+                                    this.storeCheckingReceiveItems[0].counted_amount = res.data.data.counted_amount;
+                                    this.storeCheckingReceiveItems[0].imported_diff_amount = res.data.data.imported_diff_amount;
+                                    this.storeCheckingReceiveItems[0].asn_diff_amount = res.data.data.asn_diff_amount;
+                                }else{
+                                    this._removeCheckingReceiveItem(res.data.data.id);
+                                    this._addStoreCheckingReceiveItem(res.data.data);
+                                }
+                                this.inputting.amount = res.data.data.counted_amount;
+                                window.tempTip.setDuration(2000);
+                                window.tempTip.showSuccess('成功增加“'+this.inputting.barcode+'”实盘数量')
                             }
+                            if (this.status.commitButtonVisible) this.status.commitButtonVisible=false;
                             this.audioDing();
+                            if (this.inputMode === 'regular')this.cleanInputs();
                             return;
                         }
                         window.tempTip.setDuration(3000);
@@ -252,6 +287,32 @@
                     window.tempTip.show("网络错误:"+err);
                 });
             },
+            _addStoreCheckingReceiveItem(item){
+                let storeCheckingReceiveItem = {
+                    id:item.id,
+                    bin_number:item.bin_number,
+                    commodity_name:item.commodity ? item.commodity.name : '',
+                    commodity_barcodes:item.commodity ? item.commodity.barcodes : [],
+                    imported_amount:item.imported_amount,
+                    counted_amount:item.counted_amount,
+                    asn_amount:item.asn_amount,
+                    imported_diff_amount:item.imported_diff_amount,
+                    asn_diff_amount:item.asn_diff_amount,
+                    produced_at:item.produced_at,
+                    invalid_at:item.invalid_at,
+                    batch_code:item.batch_code,
+                    unique_code:item.unique_code,
+                };
+                this.storeCheckingReceiveItems.unshift(storeCheckingReceiveItem);
+            },
+            _removeCheckingReceiveItem(id){
+                this.storeCheckingReceiveItems.some((item,index)=>{
+                    if (item.id == id){
+                        this.storeCheckingReceiveItems.splice(index,1);
+                        return true;
+                    }
+                });
+            },
             cleanInputs: function () {
                 this.inputting.barcode='';
                 this.inputting.amount='';
@@ -302,7 +363,7 @@
                     return;
                 }
                 _this.status.binDisable=true;
-                _this.inputting.amount = item.amount;
+                _this.inputting.amount = '';
                 _this.inputting.bin_number = item.bin_number;
                 if (signIncreasing && _this.lastScannedBarcode && _this.lastScannedBarcode !== _this.inputting.barcode) {
                     this.audioWarning_otherBarcode();
@@ -381,6 +442,60 @@
                     clearInterval(vibrateInterval)
                 }, 2000);
             },
+            exportItem(){
+                let url = '{{url('store/checkingReceive/mission/export?mission_id=')}}'+this.storeCheckingReceive.id;
+                window.open(url);
+            },
+            isResetAmount(){
+                window.tempTip.confirm('是否要进行重新清点,该操作会重置当前任务所有已盘数量!',()=>{
+                    this.resetAmount();
+                });
+            },
+            resetAmount(){
+              axios.post('{{url('store/checkingReceive/mission/resetAmount')}}')
+                  .then(res=>{
+                      if (res.data.success){
+                          this.storeCheckingReceiveItems.forEach(function (item) {
+                              item.counted_amount = 0;
+                              item.imported_diff_amount = '';
+                              item.asn_diff_amount = '';
+                          });
+                          window.tempTip.setDuration(2000);
+                          window.tempTip.showSuccess('重新清点完毕,数量已重置为0');
+                          return;
+                      }
+                      window.tempTip.setDuration(3000);
+                      window.tempTip.show(res.data.data);
+                  }).catch(err=>{
+                      window.tempTip.setDuration(3000);
+                      window.tempTip.show("网络错误:"+err);
+                  });
+            },
+            matchASN(){
+                if (!this.asn){
+                    window.tempTip.setIndex(1099);
+                    window.tempTip.setDuration(3000);
+                    window.tempTip.show('请输入ASN号!');
+                    return;
+                }
+                axios.post('{{url('store/checkingReceive/mission/matchASN')}}',{asn:this.asn,mission_id:this.storeCheckingReceive.id})
+                    .then(res=>{
+                        if (res.data.success){
+                            window.tempTip.setIndex(1099);
+                            window.tempTip.setDuration(2000);
+                            window.tempTip.showSuccess("匹配成功");
+                            location.reload();
+                            return;
+                        }
+                        window.tempTip.setIndex(1099);
+                        window.tempTip.setDuration(3000);
+                        window.tempTip.show(res.data.data);
+                    }).catch(err=>{
+                        window.tempTip.setIndex(1099);
+                        window.tempTip.setDuration(3000);
+                        window.tempTip.show("网络错误:"+err);
+                    });
+            }
         },
     });
 </script>

+ 4 - 0
routes/web.php

@@ -227,6 +227,10 @@ Route::group(['prefix'=>'store'],function(){
     Route::group(['prefix'=>'checkingReceive'],function(){
         Route::group(['prefix'=>'mission'],function(){
             Route::post('import','StoreCheckingReceiveController@import');
+            Route::get('export','StoreCheckingReceiveController@export');
+            Route::post('resetAmount','StoreCheckingReceiveController@resetAmount');
+            Route::post('matchASN','StoreCheckingReceiveController@matchASN');
+            Route::post('receipt','StoreCheckingReceiveController@receipt');
             Route::get('{id}','StoreCheckingReceiveController@show');
         });
         Route::post('insertItem','StoreCheckingReceiveController@insertItem');