Sfoglia il codice sorgente

点盘一体化功能

haozi 4 anni fa
parent
commit
663143428c

+ 52 - 21
app/Http/Controllers/StoreCountGoodsAndReceiveController.php

@@ -8,8 +8,11 @@ use App\InventoryBlindReceiveExcel;
 use App\OracleDOCASNDetail;
 use App\Services\HandInStorageService;
 use Carbon\Carbon;
+use Doctrine\DBAL\Exception;
 use Doctrine\DBAL\Exception\DatabaseObjectExistsException;
 use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\Cache;
 use Maatwebsite\Excel\Facades\Excel;
 
 class StoreCountGoodsAndReceiveController extends Controller
@@ -61,26 +64,10 @@ class StoreCountGoodsAndReceiveController extends Controller
         });
     }
 
-//    /**
-//     * @param Request $request
-//     * 查询富勒bas_sku 并关联 bas_lotid
-//     */
-//    public function getReceiveInfoWithLot(Request $request): array
-//    {
-//        $barcode= $request->input('barcode');
-//        $asnno= $request->input('asnno');
-//        $asnDetail=app('HandInStorageService')->getAsnDetail($asnno,$barcode);
-//        if (!$asnDetail)$this->error('无效条码');
-//        $basSku =app('HandInStorageService')->getBasSkuLotId($asnDetail->customerid,$asnDetail->sku);
-//        if (isset($basSku)&&isset($asnDetail))return ['success'=>true,'basSku'=>$basSku,'asnDetail'=>$asnDetail];
-//        else $this->error('无效条码');
-//    }
-
     public function getReceiveTaskByAsnNoAndBarcodes(Request $request)
     {
-        $asnno=$request->input('asnno');//ASN1906280001
+        $asnno=$request->input('asnno');
         $goods=$request->input('goods');
-//        $barcodes=array_diff(array_unique(data_get($goods,'*.barcode')),['','*',null]);
         $asnDetails=OracleDOCASNDetail::query()
             ->select('asnno','asnlineno','customerid','sku','expectedqty','receivedqty_each',
                 'lotatt01','lotatt02','lotatt03','lotatt04','lotatt05','lotatt08')
@@ -88,17 +75,20 @@ class StoreCountGoodsAndReceiveController extends Controller
             ->where('asnno',$asnno)
             ->whereIn('linestatus', ['00', '30'])
             ->get();
+        $status=false;
        foreach ($goods as &$good){
            foreach ($asnDetails as $asnDetail){
                if (!$asnDetail['basSku']??false)continue;
-               if ($good['barcode']==$asnDetail['basSku']['alternate_sku1']
-               ||$good['barcode']==$asnDetail['basSku']['alternate_sku2']
-               ||$good['barcode']==$asnDetail['basSku']['alternate_sku3']){
+               if ($good['sku']==$asnDetail['basSku']['alternate_sku1']
+               ||$good['sku']==$asnDetail['basSku']['alternate_sku2']
+               ||$good['sku']==$asnDetail['basSku']['alternate_sku3']){
                    $good['basSku']=$asnDetail['basSku'];
                    $good['customerid']=$asnDetail['customerid'];
                    $good['asn_amount']=($asnDetail['expectedqty']-$asnDetail['receivedqty_each']);
                    $good['diff_val']=($good['asn_amount']-$good['amount']);
                    $good['receiveStatus']=true;
+                   $status=true;
+                   $good['asnlineno']=$asnDetail['asnlineno'];
                    $good['lotatt01']=$asnDetail['lotatt01'];
                    $good['lotatt02']=$asnDetail['lotatt02'];
                    $good['lotatt03']=$asnDetail['lotatt03'];
@@ -108,7 +98,48 @@ class StoreCountGoodsAndReceiveController extends Controller
                }
            }
        }
-        $this->success($goods);
+       if ($status)$this->success($goods);
+        else $this->error('当前ASN单号未查询到下述商品信息!');
+    }
 
+    public function fluxReceive(Request $request)
+    {
+        $info=$request->input('good');
+        $isSku=$info['sku']??false;
+        if ($info['lotatt02']&&Carbon::now()->gt($info['lotatt02']))$this->error('失效日期超过入库效期');
+        if (!$info['customerid']||$isSku===false||!$info['asnno']) $this->error('参数错误');
+        /** @var HandInStorageService $handInStorageService  */
+        $handInStorageService=app('HandInStorageService');
+        if ($info['customerid']=='ONKYO'||$info['customerid']=='ANMEILAI'||$info['customerid']=='FEIHE'){
+            $res=$handInStorageService->checkWidthHeight($info);
+            if ($res===1)$this->error('需要维护产品档案');
+            if ($res===2)$this->error('需要维护该产品档案中的长宽高');
+        }
+        if ($info['customerid']=='TANGENBEI'||$info['customerid']=='ANMEILAI'){
+            $result=$handInStorageService->checkCubicWeight($info);
+            if ($result===1)$this->error('需要维护产品档案');
+            if ($result===2)$this->error('需要维护该产品档案中的重量体积');
+        }
+        if ($info['customerid']=='JIANSHANG'&&$handInStorageService->checkForwardingLoc($info)===1)$this->error('请维护拣货位');
+        $key = $info['asnno'] . '_' . $info['sku'] . '_' . Auth::id();
+        $ttl = 10;
+        try {
+            //缓存校验操作
+            if (Cache::has($key)){
+                $this->error('当前已操作');
+            }else{
+                Cache::put($key,true, $ttl);
+            }
+            //收货操作
+            $resultIn = $handInStorageService->fluxHandIn($info);
+            if ($resultIn===1)$this->error("超收");
+            if ($resultIn){
+                $this->success('收货成功');
+            } else $this->error("收货失败");
+        } catch (\Exception $e) {
+            app('LogService')->log(__METHOD__,'error_'.__FUNCTION__,json_encode($info).'|catch:'.$e->getMessage());
+        } finally {
+            Cache::forget($key);
+        }
     }
 }

+ 126 - 51
resources/views/store/countGoodsAndReceive/index.blade.php

@@ -8,7 +8,7 @@
         <audio src="{{asset('sound/ding.mp3')}}" controls="controls" preload id="soundDing" hidden>
         </audio>
         <div class="row">
-            <div class="col-4" id="countGoods">
+            <div class="col-4 p-0 m-0" id="countGoods">
                 <div class="col-12 text-center bg-white mt-2">
                     <h4 class="font-weight-bold text-dark">清点模式</h4>
                 </div>
@@ -50,18 +50,18 @@
                             </tr>
                         </table>
                         <hr>
-                        <span class="btn btn-outline-dark btn form-control" style="cursor: pointer" @click="submitExcelData">一键收货</span>
+                        <span class="btn btn-outline-dark btn form-control" style="cursor: pointer" @click="submitExcelData">结束清点</span>
                     </div>
             </div>
-            <div class="col-8" id="receive">
+            <div class="col-8 p-0 m-0" id="receive">
                 <div class="col-12 text-center bg-white mt-2">
                     <h4 class="font-weight-bold text-dark">收货模式</h4>
                 </div>
-                <div class="card-body">
+                <div class="card-body m-0">
                         <div class="col-8 offset-2 row">
                              <label for="asnno" class="font-weight-bold text-muted ">输入ASN</label>
-                            <input type="text" id="asnno" class="form-control" @focusin="focusOutDocument"
-                                   @change="getReceiveTaskByAsnNoAndBarcodes()"  placeholder="ASN单号" v-model="asnno">
+                            <input type="text" id="asnno" class="form-control" @focusin="focusOutDocument" autocomplete="off"
+                                   @change="getReceiveTaskByAsnNoAndBarcodes()" disabled="true" placeholder="ASN单号" v-model="asnno">
                         </div>
                     <table class="table table-sm table-striped" v-if="regroupGoods.length>0">
                         <hr>
@@ -82,66 +82,89 @@
                         </tr>
                         <tr v-for="(goods,i) in regroupGoods">
                             <td class="text-center">@{{ goods.customerid }}</td>
-                            <td class="text-center">@{{ goods.barcode }}</td>
+                            <td class="text-center">@{{ goods.sku }}</td>
                             <td class="text-center">@{{ goods.amount }}</td>
                             <td class="text-center">@{{ goods.asn_amount }}</td>
                             <td class="text-center">@{{ goods.diff_val }}</td>
 
                             <td class="text-center">
                                 <span v-if="goods.receiveStatus">
-                                    <input type="text" class="form-control form-control-sm" id="trackNumber" v-model="goods.trackNumber">
+                                    <input type="text" autocomplete="off" class="form-control form-control-sm" :class="errors.trackNumber ? 'is-invalid' : ''"
+                                           id="trackNumber" v-model="goods.trackNumber">
+                                    <span class="invalid-feedback offset-3" role="alert" v-if="errors.trackNumber">
+                                        <strong>@{{ errors.trackNumber[0] }}</strong>
+                                    </span>
                                 </span>
                             </td>
 
                             <td class="text-center">
-                                <span v-if="basSku.lot_id">
-                                    <input type="date" class="form-control form-control-sm input-sm"
-                                           :disabled="goods.basSku.lot_id.lotkey01==='Y' ? '' : 'true'"  id="lotatt01" v-model="goods.lotatt01">
+                                <span v-if="goods.basSku.lot_id">
+                                    <input type="date" autocomplete="off" class="form-control form-control-sm input-sm" :class="errors.lotatt01 ? 'is-invalid' : ''"
+                                           :disabled="goods.basSku.lot_id.lotkey01==='N'"  id="lotatt01" v-model="goods.lotatt01">
+                                     <span class="invalid-feedback offset-3" role="alert" v-if="errors.lotatt01">
+                                        <strong>@{{ errors.lotatt01[0] }}</strong>
+                                    </span>
                                 </span>
                             </td>
                             <td class="text-center">
-                               <span v-if="basSku.lot_id">
-                                    <input type="date" class="form-control form-control-sm input-sm"
-                                           :disabled="goods.basSku.lot_id.lotkey02==='Y' ? '' : 'true'"  id="lotatt02" v-model="goods.lotatt02">
+                               <span v-if="goods.basSku.lot_id">
+                                    <input type="date" autocomplete="off" class="form-control form-control-sm input-sm" :class="errors.lotatt02 ? 'is-invalid' : ''"
+                                           :disabled="goods.basSku.lot_id.lotkey02==='N'"  id="lotatt02" v-model="goods.lotatt02">
+                                    <span class="invalid-feedback offset-3" role="alert" v-if="errors.lotatt02">
+                                        <strong>@{{ errors.lotatt02[0] }}</strong>
+                                    </span>
                                 </span>
                             </td>
                             <td class="text-center">
-                                <span v-if="basSku.lot_id">
-                                    <input type="text" class="form-control form-control-sm input-sm"
-                                           :disabled="goods.basSku.lot_id.lotkey04==='Y' ? '' : 'true'"  id="lotatt04" v-model="goods.lotatt04">
+                                <span v-if="goods.basSku.lot_id">
+                                    <input type="text" autocomplete="off" class="form-control form-control-sm input-sm" :class="errors.lotatt04 ? 'is-invalid' : ''"
+                                           :disabled="goods.basSku.lot_id.lotkey04==='N'"  id="lotatt04" v-model="goods.lotatt04">
+                                     <span class="invalid-feedback offset-3" role="alert" v-if="errors.lotatt04">
+                                        <strong>@{{ errors.lotatt04[0] }}</strong>
+                                    </span>
                                 </span>
                             </td>
                             <td class="text-center">
-                                <span v-if="basSku.lot_id">
-                                    <select class="form-control form-control-sm" :disabled="goods.basSku.lot_id.lotkey05==='Y' ? '' : 'true'"
-                                            id="lotatt05" v-model="goods.lotatt05">
+                                <span v-if="goods.basSku.lot_id">
+                                    <select class="form-control form-control-sm" :disabled="goods.basSku.lot_id.lotkey05==='N'"
+                                            id="lotatt05" v-model="goods.lotatt05" :class="errors.lotatt05 ? 'is-invalid' : ''">
                                         <option v-for="(attributeLocation,i) in attributeLocations"
                                             :value="attributeLocation.code">@{{ attributeLocation.codename_c }}</option>
                                     </select>
+                                     <span class="invalid-feedback offset-3" role="alert" v-if="errors.lotatt05">
+                                        <strong>@{{ errors.lotatt05[0] }}</strong>
+                                    </span>
                                 </span>
                             </td>
                             <td class="text-center">
-                                <span v-if="basSku.lot_id">
-                                     <select class="form-control form-control-sm"
-                                             :disabled="goods.basSku.lot_id.lotkey08==='Y' ? '' : 'true'" id="lotatt08" v-model="goods.lotatt08">
+                                <span v-if="goods.basSku.lot_id">
+                                     <select class="form-control form-control-sm" :class="errors.lotatt08 ? 'is-invalid' : ''"
+                                             :disabled="goods.basSku.lot_id.lotkey08==='N'" id="lotatt08" v-model="goods.lotatt08">
                                         <option v-for="(quality,i) in qualityStatus"  :value="quality.code">@{{ quality.codename_c }}</option>
                                     </select>
+                                     <span class="invalid-feedback offset-3" role="alert" v-if="errors.lotatt08">
+                                        <strong>@{{ errors.lotatt08[0] }}</strong>
+                                    </span>
                                 </span>
                             </td>
                             <td class="text-center">
-                                <span v-if="basSku.lot_id">
-                                    <input type="date" class="form-control form-control-sm input-sm"
-                                           :disabled="goods.basSku.lot_id.lotkey03==='Y' ? '' : 'true'"  id="lotatt03" v-model="goods.lotatt03">
+                                <span v-if="goods.basSku.lot_id">
+                                    <input type="date" autocomplete="off" class="form-control form-control-sm input-sm" :class="errors.lotatt03 ? 'is-invalid' : ''"
+                                           :disabled="goods.basSku.lot_id.lotkey03==='N'"  id="lotatt03" v-model="goods.lotatt03">
+                                     <span class="invalid-feedback offset-3" role="alert" v-if="errors.lotatt03">
+                                        <strong>@{{ errors.lotatt03[0] }}</strong>
+                                    </span>
                                 </span>
                             </td>
-
                             <td class="text-center">
-                                <span v-if="goods.receiveStatus">
-                                    <button class="btn btn-outline-info btn-sm" @click="receiveGoods(i,goods.barcode)">收</button>
+                                <span v-if="goods.receiveStatus&&goods.diff_val>=0">
+                                    <button class="btn btn-outline-info btn-sm" @click="receiveGoods(goods)">收</button>
                                 </span>
                             </td>
                         </tr>
                     </table>
+                    <span class="btn btn-outline-dark btn form-control mt-5" v-if="status.finishReceiveButton"
+                          style="cursor: pointer" @click="finishReceive()">结束收货</span>
                 </div>
             </div>
         </div>
@@ -162,12 +185,16 @@
                     barcode:'',amount:'',fromIncreasing:true,cast_number:'',countGoodStatus:true
                 },
                 status:{
-                    scanEndInputted:false,barcodeDisable:true,amountDisable:true,
+                    scanEndInputted:false,barcodeDisable:true,amountDisable:true,finishReceiveButton:false,
                 },
                 asnno:'',
-                basSku:{},
+                basSku:{
+                    lot_id:'',
+                },
                 goodses:[],
+                initGoods:[],
                 regroupGoods:[],
+                errors:{},
             },
             mounted() {
                 if (navigator.userAgent.indexOf("Android")!==-1)this.isAndroid = true;
@@ -327,50 +354,95 @@
                 },
                 assignRegroupGoods(){
                     let data=this;
-                    data.regroupGoods=data.regroupArr(data.goodses);
-                    data.regroupGoods.forEach(function (obj){
+                    data.initGoods=data.regroupArr(data.goodses);
+                    data.initGoods.forEach(function (obj){
                         delete obj.fromIncreasing;
                         delete obj.cast_number;
                         delete obj.countGoodStatus;
-                        obj.customerid='';
-                        obj.asn_amount='';
-                        obj.diff_val='';
-                        obj.receiveStatus=false;
-                        obj.basSku='';
+                        obj.asnno='';obj.customerid='';
+                        obj.location='';obj.asn_amount='';
+                        obj.diff_val='';obj.receiveStatus=false;
+                        obj.basSku=data.basSku;obj.asnlineno='';
                         obj.lotatt01='';obj.lotatt02='';
                         obj.lotatt03='';obj.lotatt04='';
                         obj.lotatt05='';obj.lotatt08='';
                     })
+                    data.initGoods=JSON.parse(JSON.stringify(data.initGoods).replace(/barcode/g,"sku"));
+                    data.regroupGoods=data.initGoods;
                 },
-                receiveGoods(){
+                receiveGoods(goods){
                     let data=this;
-                    if(data.asnno===''||data.asnno===null||data.asnno===undefined) window.tempTip.show('请先输入ASN单号!');
-                    if (data.asnno && data.asnno.indexOf('ASN')===-1)window.tempTip.show('无效ASN号!');
-
-
+                    this.errors={};
+                    this.checkGood(goods);
+                    if (JSON.stringify(this.errors)!=='{}')return;
+                    goods.asnno=data.asnno;
+                    tempTip.setDuration(99999);
+                    tempTip.waitingTip('提交中');
+                    let url='{{url("store/countGoodsAndReceive/fluxReceive")}}';
+                    axios.post(url,{good:goods})
+                        .then(function(res){
+                            if(res.data.success){
+                                data.regroupGoods.forEach(function (good,i){
+                                    if (goods.sku==good.sku){
+                                        data.regroupGoods.splice(i,1)
+                                    }
+                                })
+                                tempTip.setDuration(2000);
+                                tempTip.cancelWaitingTip();
+                                tempTip.showSuccess(res.data.data);
+                            }else{
+                                tempTip.setDuration(3000);
+                                tempTip.cancelWaitingTip();
+                                tempTip.show(res.data.data);
+                                data.alertVibrate()
+                            }
+                        })
+                        .catch(function (err) {
+                            tempTip.setDuration(2000);
+                            tempTip.cancelWaitingTip();
+                            tempTip.show("网络错误:"+err);
+                            data.alertVibrate()
+                        });
+                },
+                checkGood(good){
+                    let error = {};
+                    if (!good.trackNumber)error.trackNumber = ["容器号必填"];
+                    if (good.basSku.lot_id && good.basSku.lot_id.lotkey01==='Y' && !good.lotatt01) error.lotatt01=["生产日期为选"];
+                    if (good.basSku.lot_id && good.basSku.lot_id.lotkey02==='Y' && !good.lotatt02) error.lotatt02=["失效日期为选"];
+                    if (good.basSku.lot_id && good.basSku.lot_id.lotkey03==='Y' && !good.lotatt03) error.lotatt03=["入库日期为选"];
+                    if (good.basSku.lot_id && good.basSku.lot_id.lotkey04==='Y' && !good.lotatt04) error.lotatt04=["批号未填"];
+                    if (good.basSku.lot_id && good.basSku.lot_id.lotkey05==='Y' && !good.lotatt05) error.lotatt05=["属性仓未选"];
+                    if (good.basSku.lot_id && good.basSku.lot_id.lotkey08==='Y' && !good.lotatt08) error.lotatt08=["质量状态未选"];
+                    if (JSON.stringify(error)!=='{}'){this.errors = error;}
                 },
                 getReceiveTaskByAsnNoAndBarcodes(){
                     let data=this;
+                    data.regroupGoods=data.initGoods;//验证asn下商品时 初始商品数据
                     if(data.asnno===''||data.asnno===null||data.asnno===undefined) window.tempTip.show('请先输入ASN单号!');
                     if (data.asnno && data.asnno.indexOf('ASN')===-1)window.tempTip.show('无效ASN号!');
                     let url='{{url("store/countGoodsAndReceive/getReceiveTaskByAsnNoAndBarcodes")}}';
-                    window.axios.post(url,{asnno:data.asnno,goods:data.regroupGoods})
+                    window.axios.post(url,{asnno:data.asnno,goods:data.initGoods})
                         .then(res=>{
                             if (res.data.success){
                                 data.regroupGoods=res.data.data;
                                 this.$forceUpdate()
-                                console.log(data.regroupGoods)
                             }else {
-
+                                tempTip.setDuration(3000);
+                                tempTip.show(res.data.data);
                             }
                         }).catch(err=>{
                         window.tempTip.setDuration(2000);
                         window.tempTip.show("网络错误:"+err);
                     })
                 },
+                removeDisable(){
+                    let asnNo=$('#asnno');
+                    asnNo.removeAttr('disabled');
+                    this.status.finishReceiveButton=true;
+                    asnNo.focus();
+                },
                 submitExcelData: function () {
                     let data = this;
-                    data.assignRegroupGoods();
                     data.focusOutDocument();
                     if(data.goodses.length===0){
                         window.tempTip.show('请先录入数据再提交收货');return;
@@ -396,17 +468,16 @@
                                 axios.post(url,{'goodses':data.goodses,'filename':val})
                                     .then(function(response){
                                         if(response.data.result==='success'){
-                                            data.assignRegroupGoods();//统计清点信息,并生成收货所需数据
+                                            data.removeDisable();//收货解锁asnno input标签
+                                            data.assignRegroupGoods();//结束清点,重组收货所需数据
                                             data.goodses=[];
                                             data.cleanInputs();
                                             window.tempTip.cancelWaitingTip();
                                             window.tempTip.setDuration(1500);
                                             window.tempTip.showSuccess('成功生成EXCEL,可在列表页查看');
-                                            data.focusDocument();
                                         }else{
                                             window.tempTip.setDuration(1500);
-                                            window.tempTip.show('生成EXCEL失败:'+response.data.fail_info);
-                                            console.log(response);
+                                            window.tempTip.show('生成EXCEL失败');
                                             data.focusDocument();
                                             data.alertVibrate()
                                         }
@@ -422,6 +493,10 @@
                         },function () {
                             data.focusDocument();
                         })
+                },
+                finishReceive(){
+                    if(!confirm('确定要结束收货吗?'))return;
+                    setTimeout(function (){window.location.reload()},10)
                 }
             },
         });

+ 1 - 0
routes/web.php

@@ -565,6 +565,7 @@ Route::group(['prefix'=>'package'],function(){
             Route::get('index', 'StoreCountGoodsAndReceiveController@index');
             Route::get('excel', 'StoreCountGoodsAndReceiveController@excel');
             Route::post('createExcel', 'StoreCountGoodsAndReceiveController@createExcel');
+            Route::any('fluxReceive','StoreCountGoodsAndReceiveController@fluxReceive');
             Route::post('getReceiveTaskByAsnNoAndBarcodes', 'StoreCountGoodsAndReceiveController@getReceiveTaskByAsnNoAndBarcodes');
         });
         Route::group(['prefix'=>'fast'],function() {