'收货单', self::two => '发货单',//确认后出库 self::three => '采购单',//确认后入库 self::four => '合同', self::five => '施工单',//确认后出库 self::six => '退换货单',//确认后出库或出库入库 self::seven => '采购单确认', ]; //入库操作 public static $in_opt = [ self::three, ]; //出库操作 public static $out_opt = [ self::two, self::five, ]; const TYPE_ONE = 1;//通过 const TYPE_TWO = 2;//不通过 //单据操作 public static $opt_case = [ self::two => 'confirmInvoiceOrder', self::three => 'confirmPurchaseOrder', self::five => 'confirmConstruction', self::six => 'confirmReturnExchangeOrder', self::seven => 'confirmPurchaseOrderState' ]; //单据库存流水 public static $record = [ self::two => 'recordInvoiceOrder', self::three => 'recordPurchaseOrder', self::five => 'recordConstruction', self::six => 'recordReturnExchangeOrder' ]; public static $create = [ self::seven => 'createPurchaseOrderSales', //分社合同生成 ]; public function confirmInvoiceOrder($data){ $model = InvoiceOrder::where('id',$data['id']) ->where('del_time',0) ->first(); if(empty($model)) return [false, '发货单不存在或已被删除']; if($model->state != InvoiceOrder::STATE_ZERO) return [false, '请确认发货单状态,操作失败']; InvoiceOrder::where('del_time',0)->where('id',$data['id']) ->update(['state' => InvoiceOrder::STATE_ONE]); SalesOrder::where('id',$model->sales_order_id)->update(['state' => SalesOrder::State2_one]); return [true, $model->toArray()]; } public function recordInvoiceOrder($data, $order){ $result = InvoiceOrderInfo::where('del_time',0) ->where('order_number',$order['order_number']) ->get()->toArray(); if(empty($result)) return [false,'发货单产品信息不存在或已被删除']; $insert = []; $time = time(); foreach ($result as $value){ $key = $value['product_id'] . $value['storehouse_id']; if(isset($insert[$key])){ $insert[$key]['number'] += -($value['number']); }else{ $insert[$key] = [ 'product_id' => $value['product_id'], 'number' => -($value['number']), 'order_type' => InvoiceOrder::prefix, 'order_number' => $order['order_number'], 'crt_time' => $time, 'storehouse_id' => $value['storehouse_id'], 'depart_id' => $order['depart_id'], 'top_depart_id' => $order['top_depart_id'], ]; } } $insert = array_values($insert); $bool = InOutRecord::insert($insert); if(! $bool) return [false,'流水写入失败']; return [true,'']; } public function confirmPurchaseOrderState($data){ $model = PurchaseOrder::where('id',$data['id']) ->where('del_time',0) ->first(); if(empty($model)) return [false,'采购单不存在或已被删除']; if(! empty($model->state)) return [false,'采购单已确认']; PurchaseOrder::where('id',$data['id'])->update(['state' => PurchaseOrder::STATE_ONE]); return [true, $model->toArray()]; } public function confirmPurchaseOrder($data){ $model = PurchaseOrder::where('id',$data['id']) ->where('del_time',0) ->first(); if(empty($model)) return [false, '采购订单不存在或已被删除']; if($model->state != PurchaseOrder::STATE_ONE) return [false, '请确认采购订单状态,操作失败']; PurchaseOrder::where('del_time',0)->where('id',$data['id']) ->update(['state' => PurchaseOrder::STATE_TWO]); return [true, $model->toArray()]; } public function recordPurchaseOrder($data, $order){ $result = PurchaseOrderInfo::where('del_time',0) ->where('order_number',$order['order_number']) ->get()->toArray(); if(empty($result)) return [false,'采购单产品信息不存在或已被删除']; $insert = []; $time = time(); foreach ($result as $value){ $key = $value['product_id'] . $value['storehouse_id']; if(isset($insert[$key])){ $insert[$key]['number'] += $value['number']; }else{ $insert[$key] = [ 'product_id' => $value['product_id'], 'number' => $value['number'], 'order_type' => PurchaseOrder::prefix, 'order_number' => $order['order_number'], 'crt_time' => $time, 'storehouse_id' => $value['storehouse_id'], 'depart_id' => $order['depart_id'], 'top_depart_id' => $order['top_depart_id'], ]; } } $insert = array_values($insert); $bool = InOutRecord::insert($insert); if(! $bool) return [false,'流水写入失败']; return [true,'']; } //todo public function createPurchaseOrderSales($data, $order, $user){ //没有供应商 不创建合同 if(empty($order['supplier'])) return [true, '']; //总公司的采购单 不创建合同 $top_depart_id = $user['head'] ?? []; if($top_depart_id['id'] == $order['top_depart_id']) return [true, '']; //分社公司的采购单 不向总供应商采购 不创建合同 $is_create = Supplier::where('id',$order['supplier'])->value('is_main'); if(empty($is_create)) return [true, '']; $prefix = SalesOrder::$prefix[SalesOrder::Model_type_two]; $order_number = OrderNoService::createSalesOrderNumber($prefix); $product = PurchaseOrderInfo::where('del_time',0) ->where('purchase_order_id',$order['id']) ->get()->toArray(); if(empty($product)) return [false, '采购订单产品数据不能为空']; $depart_id = Depart::where('del_time',0)->where('parent_id',0)->where('is_main',1)->value('id'); $model = new SalesOrder(); $model->model_type = SalesOrder::Model_type_two; $model->sales_order_type = SalesOrder::Order_type_one; $model->order_number = $order_number; $model->crt_id = $order['crt_id']; $model->depart_id = $depart_id; $model->top_depart_id = $depart_id; $model->other_fee = $order['other_fee']; $model->discount_fee = $order['discount_fee']; $model->contract_fee = $order['purchase_total']; $model->save(); //产品字典 $map = (new ProductService())->getProductDetail(array_column($product,'product_id')); $insert = []; foreach ($product as $value){ $tmp = $map[$value['product_id']] ?? []; $insert[] = [ 'sales_order_id' => $model->id, 'product_id' => $value['product_id'], 'number' => $value['number'], 'basic_type_id' => $value['basic_type_id'], 'price' => $value['price'], 'cost' => $tmp['cost'] ?? 0, 'retail_price' => $tmp['retail_price'] ?? 0, ]; } $bool = SalesOrderProductInfo::insert($insert); if(! $bool) return [false,'合同生成失败!']; return [true,'']; } public function confirmConstruction($data){ $model = Construction::where('id',$data['id']) ->where('del_time',0) ->first(); if(empty($model)) return [false, '施工单不存在或已被删除']; if($model->state != Construction::STATE_ZERO) return [false, '请确认施工单状态,操作失败']; Construction::where('del_time',0)->where('id',$data['id']) ->update(['state' => Construction::STATE_ONE]); SalesOrder::where('id',$model->sales_order_id)->update(['state' => SalesOrder::State_three]); return [true, $model->toArray()]; } public function recordConstruction($data, $order){ $result = ConstructionProductInfo::where('del_time',0) ->where('construction_id',$order['id']) ->get()->toArray(); if(empty($result)) return [false,'施工单产品信息不存在或已被删除']; $insert = []; $time = time(); foreach ($result as $value){ $key = $value['product_id'] . $value['storehouse_id']; if(isset($insert[$key])){ $insert[$key]['number'] += -($value['number']); }else{ $insert[$key] = [ 'product_id' => $value['product_id'], 'number' => -($value['number']), 'order_type' => Construction::$prefix[$order['model_type']] ?? '', 'order_number' => $order['order_number'], 'crt_time' => $time, 'storehouse_id' => $value['storehouse_id'], 'depart_id' => $order['depart_id'], 'top_depart_id' => $order['top_depart_id'], ]; } } $insert = array_values($insert); $bool = InOutRecord::insert($insert); if(! $bool) return [false,'流水写入失败']; return [true,'']; } public function confirmReturnExchangeOrder($data){ $model = ReturnExchangeOrder::where('id',$data['id']) ->where('del_time',0) ->first(); if(empty($model)) return [false, '退换货单不存在或已被删除']; if($model->state != ReturnExchangeOrder::State_zero) return [false, '请确认退换货单状态,操作失败']; ReturnExchangeOrder::where('del_time',0)->where('id',$data['id']) ->update(['state' => ReturnExchangeOrder::State_one]); if($data['data_type'] == ReturnExchangeOrder::Order_type){ SalesOrder::where('id',$data['id'])->update([ 'state' => SalesOrder::State_four ]); } return [true, $model->toArray()]; } public function recordReturnExchangeOrder($data, $order){ $result = ReturnExchangeOrderProductInfo::where('del_time',0) ->where('return_exchange_id',$order['id']) ->get()->toArray(); if(empty($result)) return [false,'退换货单产品信息不存在或已被删除']; $insert = $insert2 = []; $time = time(); foreach ($result as $value){ $key = $value['product_id'] . $value['storehouse_id']; $prefix = ReturnExchangeOrder::$prefix[$value['return_or_exchange']] ?? ''; if($value['return_or_exchange'] == ReturnExchangeOrderProductInfo::type_one){ //退货 if(isset($insert[$key])){ $insert[$key]['number'] += $value['number']; }else{ $insert[$key] = [ 'product_id' => $value['product_id'], 'number' => $value['number'], 'order_type' => $prefix, 'order_number' => $order['order_number'], 'crt_time' => $time, 'storehouse_id' => $value['storehouse_id'], 'depart_id' => $order['depart_id'], 'top_depart_id' => $order['top_depart_id'], ]; } }else{ //换货 if(isset($insert2[$key])){ $insert2[$key]['number'] += -($value['number']); }else{ $insert2[$key] = [ 'product_id' => $value['product_id'], 'number' => -($value['number']), 'order_type' => $prefix, 'order_number' => $order['order_number'], 'crt_time' => $time, 'storehouse_id' => $value['storehouse_id'], 'depart_id' => $order['depart_id'], 'top_depart_id' => $order['top_depart_id'], ]; } } } $insert = array_values($insert); $bool = InOutRecord::insert($insert); if(! $bool) return [false,'流水写入失败']; if(! empty($insert2)) { $insert2 = array_values($insert2); $bool = InOutRecord::insert($insert2); if(! $bool) return [false,'流水写入失败']; } return [true,'']; } public function checkAll($data,$user){ if(empty($data['id']) || empty($data['opt_case'])) return [false,'必传参数不能为空或者参数值错误!']; //具体方法 $function = self::$opt_case[$data['opt_case']] ?? ""; $record = self::$record[$data['opt_case']] ?? ""; $create = self::$create[$data['opt_case']] ?? ""; try{ DB::beginTransaction(); list($bool,$msg) = $this->$function($data); if(! $bool){ DB::rollBack(); return [false, $msg]; } $order = $msg; if($record) { //流水 $bool = $this->$record($data, $order); if(! $bool) { DB::rollBack(); return [false, $msg]; } //库存 $bool = $this->changeInventory($data, $order, $user); if(! $bool) { DB::rollBack(); return [false, $msg]; } } if($create) { $bool = $this->$create($data, $order, $user); if(! $bool) { DB::rollBack(); return [false, $msg]; } } DB::commit(); return [true, '']; }catch (\Throwable $exception){ DB::rollBack(); return [false, $exception->getMessage()]; } } //更新库存 public function changeInventory($data,$order,$user){ $number_symbol = ""; if(in_array($data['opt_case'],self::$in_opt)){ $number_symbol = ">"; }elseif (in_array($data['opt_case'],self::$out_opt)){ $number_symbol = "<"; } //获取单据最新数据时间 正常审核的数据 $latest = InOutRecord::where('del_time',0) ->where('order_number',$order['order_number']) ->when(! empty($number_symbol), function ($query) use ($number_symbol) { return $query->where('number', $number_symbol,0); }) ->select('crt_time') ->orderBy('crt_time', 'desc') ->first(); $model = InOutRecord::where('del_time',0) ->where('order_number',$order['order_number']) ->when(! empty($number_symbol), function ($query) use ($number_symbol) { return $query->where('number', $number_symbol,0); }) ->select('number','crt_time','product_id','storehouse_id','top_depart_id'); if(! empty($latest)) { $t = $latest->toArray(); $model->where('crt_time',$t['crt_time']); } $record = $model->get()->toArray(); if (empty($record)) return [false,'流水记录不存在']; $result = $lock_number = []; foreach ($record as $value){ $key = $value['product_id'] . $value['storehouse_id']; if(isset($result[$key])){ $result[$key]['number'] += $value['number']; }else{ $result[$key] = [ 'product_id' => $value['product_id'], 'number' => $value['number'], 'crt_time' => $value['crt_time'], 'storehouse_id' => $value['storehouse_id'], 'top_depart_id' => $value['top_depart_id'], ]; } if($value['number'] < 0){ if(isset($lock_number[$key])){ $lock_number[$key] += $value['number']; }else{ $lock_number[$key] = $value['number']; } } } //是否锁定 $lock = 0; if($user['head']['id'] != $order['top_depart_id']) $lock = DB::table('depart_set')->where('top_depart_id',$order['top_depart_id'])->value('param_one'); $result = array_values($result); foreach ($result as $key => $value){ $keys = $value['product_id'] . $value['storehouse_id']; $m = ProductInventory::where('product_id',$value['product_id']) ->where('storehouse_id',$value['storehouse_id']) ->select('product_id','number','storehouse_id') ->first(); if(empty($m)){ ProductInventory::insert($result[$key]); }else{ $lock_number_tmp = 0; if($lock && ! empty($lock_number[$keys])) $lock_number_tmp = $lock_number[$keys]; ProductInventory::where('product_id',$m->product_id) ->where('storehouse_id',$m->storehouse_id) ->lockForUpdate() ->update([ 'number' => DB::raw('number + ('. $value['number'] . ')'), 'lock_number' => DB::raw('lock_number + ('. $lock_number_tmp . ')') ]); } } return [true,'']; } }