orderRule($data, $user,false); if(!$status) return [$status,$msg]; try{ DB::beginTransaction(); $inventory_model = Inventory::where('order_number',$data['order_number'])->first(); $inventory_model->counted_id = $data['counted_id']; $inventory_model->counted_time = $data['counted_time']; $inventory_model->mark = $data['mark']; $inventory_model->save(); InventorySub::where('del_time',0) ->where('order_number',$data['order_number']) ->update(['del_time'=>time()]); if(! empty($data['sub'])){ $sub = []; foreach ($data['sub'] as $value){ $sub[] = [ 'product_id' => $value['product_id'], 'storehouse_id' => $data['storehouse_id'], 'order_number' => $data['order_number'], 'counted_num' => $value['counted_num'], 'add_num' => $value['add_num'], 'reduce_num' => $value['reduce_num'], 'price' => $value['price'] ?? 0, 'inventory_id' => $inventory_model->id ]; } InventorySub::insert($sub); ProductInventoryService::changeLockNumber($user,$msg[0],$msg[1]); } DB::commit(); }catch (\Throwable $e){ DB::rollBack(); return [false,$e->getMessage()]; } return [true, '']; } public function add($data,$user){ list($status,$msg) = $this->orderRule($data, $user); if(!$status) return [$status,$msg]; try{ DB::beginTransaction(); $inventory_model = new Inventory(); $inventory_model->order_number = $data['order_number']; $inventory_model->storehouse_id = $data['storehouse_id']; $inventory_model->counted_id = $data['counted_id']; $inventory_model->counted_time = $data['counted_time']; $inventory_model->mark = $data['mark'] ?? ''; $inventory_model->depart_id = $data['depart_id'] ?? 0; $inventory_model->top_depart_id = $data['top_depart_id'] ?? 0; $inventory_model->crt_id = $user['id']; $inventory_model->save(); if(! empty($data['sub'])){ $sub = []; foreach ($data['sub'] as $value){ $sub[] = [ 'product_id' => $value['product_id'], 'storehouse_id' => $data['storehouse_id'], 'order_number' => $data['order_number'], 'counted_num' => $value['counted_num'], 'add_num' => $value['add_num'], 'reduce_num' => $value['reduce_num'], 'price' => $value['price'] ?? 0, 'inventory_id' => $inventory_model->id ]; } InventorySub::insert($sub); ProductInventoryService::changeLockNumber($user,$msg[0],[]); } //单据创建时是否校验库存 (new CheckService())->orderInventoryInsert(['order_number' => $data['order_number'], 'is_check_stock' => $data['is_check_stock']]); DB::commit(); }catch (\Throwable $exception){ DB::rollBack(); if (str_contains($exception->getMessage(), '1062') || str_contains($exception->getMessage(), 'Duplicate entry')) { return [false, '网络波动,请重新操作!']; } return [false,$exception->getMessage()]; } return [true, '']; } public function detail($data,$user){ if(empty($data['id']) && empty($data['order_number'])) return [false,'请选择数据!']; if(! empty($data['id'])){ $inventory = Inventory::where('del_time',0) ->where('id',$data['id']) ->first(); }else{ $inventory = Inventory::where('del_time',0) ->where('order_number',$data['order_number']) ->first(); $data['id'] = empty($inventory->id) ? 0 : $inventory->id; } if(empty($inventory)) return [false,'盘点单不存在或已被删除']; $inventory = $inventory->toArray(); $inventory['state_title'] = Inventory::$name[$inventory['state']] ?? ''; $emp_map = Employee::whereIn('id', [$inventory['crt_id'], $inventory['counted_id']]) ->pluck('emp_name','id') ->toArray(); $inventory['crt_name'] = $emp_map[$inventory['crt_id']] ?? ''; $inventory['counted_name'] = $emp_map[$inventory['counted_id']] ?? ''; $inventory['counted_time'] = $inventory['counted_time'] ? date("Y-m-d", $inventory['counted_time']): ''; $inventory['crt_time'] = $inventory['crt_time'] ? date("Y-m-d H:i:s", $inventory['crt_time']): ''; $sub = InventorySub::where('del_time',0) ->where('inventory_id', $data['id']) ->select('product_id','counted_num','add_num','reduce_num','price') ->get()->toArray(); $map = (new ProductService())->getProductDetail(array_column($sub,'product_id')); foreach ($sub as $key => $value){ $tmp = $map[$value['product_id']] ?? []; $sub[$key]['title'] = $tmp['title'] ?? ""; $sub[$key]['code'] = $tmp['code'] ?? ""; } $inventory['sub'] = $sub; return [true, $inventory]; } public function del($data,$user){ if($this->isEmpty($data,'id')) return [false,'请选择数据!']; $inventory = Inventory::where('del_time',0)->where('id',$data['id'])->first(); if(empty($inventory)) return [false,'盘点单不存在或已被删除']; $inventory = $inventory->toArray(); if($inventory['state'] > Inventory::STATE_ZERO) return [false,'请确认盘点单状态,操作失败']; $time = time(); $product_save = $this->getSaveDetail($data['id']); try { DB::beginTransaction(); Inventory::where('id',$data['id'])->update([ 'del_time'=> $time ]); InventorySub::where('del_time',0)->whereIn('inventory_id',$data['id'])->update([ 'del_time'=> $time ]); //锁定库存释放 if(! empty($product_save)) ProductInventoryService::changeLockNumber($user,[],$product_save); DB::commit(); }catch (\Exception $exception){ DB::rollBack(); return [false, $exception->getMessage()]; } return [true, '']; } public function getList($data,$user){ $model = Inventory::Clear($user,$data); $model = $model->where('del_time',0) ->select('order_number','id','storehouse_id','state','counted_id','counted_time','inventory_id','crt_time') ->orderby('id', 'desc'); if(! empty($data['crt_time'][0]) && ! empty($data['crt_time'][1])) $model->whereBetween('crt_time',[$data['crt_time'][0],$data['crt_time'][1]]); if(! empty($data['order_number'])) $model->where('order_number', 'LIKE', '%'.$data['order_number'].'%'); if(! empty($data['storehouse_id'])) $model->where('storehouse_id', $data['storehouse_id']); if(! empty($data['counted_name'])) { $id = $this->forSearch($data); $model->whereIn('counted_id',$id); } if(isset($data['state'])) $model->where('state', $data['state']); if(! empty($data['product_code'])) { $id = $this->forSearch($data); $model->whereIn('id',$id); } $list = $this->limit($model,'',$data); $list = $this->fillListData($list); return [true, $list]; } public function fillListData($data){ if(empty($data['data'])) return $data; $storehouse_map = Storehouse::whereIn('id',array_column($data['data'],'storehouse_id')) ->pluck('title','id') ->toArray(); $emp_map = Employee::whereIn('id',array_unique(array_merge_recursive(array_column($data['data'],'counted_id'), array_column($data['data'],'crt_id')))) ->pluck('emp_name','id') ->toArray(); foreach ($data['data'] as $key => $value){ $data['data'][$key]['counted_time'] = $value['counted_time'] ? date("Y-m-d",$value['counted_time']) : ''; $data['data'][$key]['crt_time'] = $value['crt_time'] ? date("Y-m-d H:i:s",$value['crt_time']) : ''; $data['data'][$key]['storehouse_name'] = $storehouse_map[$value['storehouse_id']] ?? ''; $data['data'][$key]['counted_name'] = $emp_map[$value['counted_id']] ?? ''; $data['data'][$key]['state_name'] = Inventory::$name[$value['state']] ?? ''; } return $data; } public function forSearch($data){ if(! empty($data['product_code'])){ $product = Product::where('code', 'LIKE', '%'.$data['product_code'].'%') ->select('id') ->get()->toArray(); $inventory_id = InventorySub::where('del_time',0) ->whereIn('product_id', array_column($product,'id')) ->select('inventory_id') ->get()->toArray(); return array_column($inventory_id, 'inventory_id'); } if(! empty($data['counted_name'])){ $employee = Employee::where('emp_name', 'LIKE', '%'.$data['counted_name'].'%') ->select('id') ->get()->toArray(); return array_column($employee, 'id'); } return []; } public function orderRule(&$data, $user, $is_add = true){ if(empty($data['counted_id'])) return [false,'盘点人不能为空']; if(empty($data['counted_time'])) return [false,'盘点日期不能为空']; $data['counted_time'] = $this->changeDateToDate($data['counted_time']); if(empty($data['storehouse_id'])) return [false,'仓库不能为空']; if(empty($data['sub'])) return [false, '盘点明细不能为空']; $product_submit = $product_submit_reduce = $product_id = []; foreach ($data['sub'] as $value){ if(empty($value['product_id'])) return [false,"盘点单产品ID不为空"]; $bool = $this->checkNumber($value['counted_num']); if(! $bool) return [false, '盘点数量不合法,请输入大于等于0的两位数值']; $bool = $this->checkNumber($value['add_num']); if(! $bool) return [false, '盘盈数量不合法,需是大于等于0的两位数值']; $bool = $this->checkNumber($value['reduce_num']); if(! $bool) return [false, '盘亏数量不合法,需是大于等于0的两位数值']; if(isset($value['price'])){ $bool = $this->checkNumber($value['price']); if(! $bool) return [false, '盘点单价不合法,需是大于等于0的两位数值']; } $key = $value['product_id'] . ',' .$data['storehouse_id']; if(! isset($product_submit[$key])) $product_submit[$key] = 0; if($value['reduce_num'] > 0){ if(isset($product_submit_reduce[$key])){ $product_submit_reduce[$key] += $value['reduce_num']; }else{ $product_submit_reduce[$key] = $value['reduce_num']; } $product_id[] = $value['product_id']; } } //所属部门 以及 顶级部门 if(empty($data['depart_id'])) { $data['depart_id'] = $this->getDepart($user); $data['top_depart_id'] = $user['depart_map'][$data['depart_id']] ?? 0; } $data['is_check_stock'] = $user['is_check_stock']; if($is_add){ $order_number = (new OrderNoService())->createOrderNumber(Inventory::prefix); if(empty($order_number)) return [false,'盘点单号生成失败']; $data['order_number'] = $order_number; }else{ if(empty($data['order_number'])) return [false,'盘点单号不能为空']; $model = Inventory::where('order_number',$data['order_number'])->where('del_time',0)->first(); if(empty($model)) return [false, '盘点单不存在或已被删除']; $order = $model->toArray(); if($order['state'] != Inventory::STATE_ZERO) return [false, '请确认单据状态,编辑失败']; if($order['storehouse_id'] != $data['storehouse_id']) return [false, '仓库不允许编辑']; } //校验是否存在产品盘点 list($status, $msg) = $this->issetProduct($data, $product_submit); if(! $status) return [false, $msg]; $id = $data['id'] ?? 0; $product_save_reduce = $this->getSaveDetail($id); if(! empty($product_submit_reduce)){ //校验库存 list($status,$msg) = (new ProductInventoryService())->compareStock($user,$product_id, $product_submit_reduce, $product_save_reduce); if(! $status) return [false, $msg]; } return [true, [$product_submit_reduce, $product_save_reduce]]; } /** * 获取保存详情 * @param $id * @return array */ public function getSaveDetail($id){ $product_save = []; if(empty($id)) return []; $sub = InventorySub::where('inventory_id',$id) ->where('del_time',0) ->get()->toArray(); foreach ($sub as $value){ $key = $value['product_id'] . ',' . $value['storehouse_id']; if($value['reduce_num'] > 0){//盘亏 if(isset($product_save[$key])){ $product_save[$key] += $value['reduce_num']; }else{ $product_save[$key] = $value['reduce_num']; } } } return $product_save; } public function issetProduct($data, $product_submit){ $id = $data['id'] ?? 0; $inventory = Inventory::where('del_time',0) ->when(! empty($id), function ($query) use ($id) { return $query->where('id','<>',$id); }) ->where('top_depart_id',$data['top_depart_id']) ->where('state','<',Inventory::STATE_TWO) ->select('id') ->get()->toArray(); $sub = InventorySub::where('del_time', 0) ->whereIn('inventory_id', array_column($inventory,'id')) ->select('product_id', 'storehouse_id') ->get()->toArray(); $map = []; $product = Product::whereIn('id', array_unique(array_column($sub,'product_id'))) ->select('id','title','code') ->get()->toArray(); foreach ($product as $value){ $map[$value['id']] = $value; } foreach ($sub as $value){ $key = $value['product_id'] . ',' .$value['storehouse_id']; if(isset($product_submit[$key])){ $pro_tmp = $map[$value['product_id']] ?? []; $pro_str = $pro_tmp['title'] . "( ". $pro_tmp['code'] .")"; return [false, "产品:" . $pro_str . "在盘点单:" . $value['order_number'] . "已录入盘点"]; } } return [true, '']; } }