<?php
declare (strict_types = 1);

namespace app\admin\model;

use think\Exception;
use think\Model;

/**
 * @mixin \think\Model
 */
class GoodStockInfo extends Model
{

    /**
	* @param int $stockid 仓库库存id
	* @param string $bn bn编号
	* @param int $num  bn数量
	* @param float $origin_price 采购成本价
	* @return bool  入库bn库存数新建 或退回bn库存数
	*/
    static function AddBn(int $stockid,string $bn,int $num,float $origin_price=0){
		$data=self::where(["stockid"=>$stockid,"bnCode"=>$bn])->findOrEmpty()->toArray();
		if(empty($data)){
			$data=[
				"stockid"=>$stockid,
				"bnCode"=>$bn,
				"total_num"=>$num,
				"used_num"=>0,
				"balance_num"=>$num,
				"origin_price"=>$origin_price,
				"addtime"=>date("Y-m-d H:i:s"),
				"updatetime"=>date("Y-m-d H:i:s")
				];
			$result=self::insert($data);
		}else{
			$total_num = $data["balance_num"]+$num;
			if($total_num> $data["total_num"]) throw new Exception("批次入库数量超过总数",1006);
			$temp=[];
			$temp["balance_num"]=$total_num;
			$temp["used_num"]=$data["used_num"]-$num;
			$temp["updatetime"]=date("Y-m-d H:i:s");
			$result=self::update($temp,$data)->getNumRows();
		}

		return $result;
    }

	/**
	* @param int $stockid
	* @param int $num
	 * @return array  库存品下单消耗bn库存数
	* @throws \think\Exception
	* @throws \think\db\exception\DataNotFoundException
	* @throws \think\db\exception\DbException
	* @throws \think\db\exception\ModelNotFoundException
	*/
	static function SaleBn($stockid,int $num,int $isstock=1){
		$arr = self::where([["balance_num",">",0]])->where(["stockid"=>$stockid])->select()->toArray();
		if(empty($arr)) throw new Exception("库存批次数量不足",1006);
		$list=[];
		foreach ($arr as $item) {
			$stock = self::name("good_stock")->where(["id"=>$item['stockid']])->field("id,usable_stock,wait_out_stock")->find()->toArray();
			if($num<=0) break;
			$update=[];
		    if($item['balance_num']<=$num){
		    	$update['balance_num'] =0;
		    	$update['used_num']= $item['used_num']+$item['balance_num'];
		    	$num-=$item['balance_num'];
		    	$update['updatetime'] =date("Y-m-d H:i:s");
		    	$temp=["stockid"=>$item['stockid'],"bnCode"=>$item['bnCode'],"num"=>$item['balance_num'],"origin_price"=>$item["origin_price"]];
		    	$stockup=["usable_stock"=>$stock['usable_stock']-$item['balance_num'],"wait_out_stock"=>$stock['wait_out_stock']+$item['balance_num'],"updatetime"=>date("Y-m-d H:i:s")];
		    }else{
				$update['balance_num']=$item['balance_num']-$num;
		    	$update['used_num']=$item['used_num']+$num;
		    	$update['updatetime'] =date("Y-m-d H:i:s");
		    	$temp=["stockid"=>$item['stockid'],"bnCode"=>$item['bnCode'],"num"=>$num,"origin_price"=>$item["origin_price"]];
		    	$stockup=["usable_stock"=>$stock['usable_stock']-$num,"wait_out_stock"=>$stock['wait_out_stock']+$num,"updatetime"=>date("Y-m-d H:i:s")];
				$num=0;
		    }
			$up=self::update($update,$item);
		    if($up==false)  throw new Exception("库存批次库存更新失败",1006);
		    $stup=self::name("good_stock")->where($stock)->update($stockup);
		    if($stup==false)  throw new Exception("库存更新失败",1006);
		    $list[]=$temp;
		}
		return $list;
    }
	/**
	* @param int $stockid
	* @param string $bn
	* @param int $num
	* @return bool  盘点修改bn仓库库存数
	* @throws \think\Exception
	*/
	static function CheckBn(int $stockid,string $bn,int $num){
		$data=self::where(["stockid"=>$stockid,"bnCode"=>$bn])->findOrEmpty()->toArray();
		if(empty($data)) throw new Exception("未找到Bn库存数据",1006);
			$update=[];
			$update["balance_num"]=$num;
			$update["total_num"]=$data["used_num"]+$num;
			$update["updatetime"]=date("Y-m-d H:i:s");
		return self::update($update,$data)->getNumRows();
    }
	/**
	* @param string $orderCode
	* @param int|array $stockid
	* @param int $num
	 * @return int
	* @throws \think\Exception
	* @throws \think\db\exception\DataNotFoundException
	* @throws \think\db\exception\DbException
	* @throws \think\db\exception\ModelNotFoundException
	 */
	static function OrderBn(string $orderCode, $stockid,int $num,int $isstock=1){
        $bnArr=self::SaleBn($stockid,$num,$isstock);
        if(empty($bnArr)) throw new Exception("未找到Bn库存数据",1006);
        $ordBn=[];
        foreach ($bnArr as $value){
	        $saleBn=[
	        "orderCode"=>$orderCode,
	        "bnCode"=>$value['bnCode'],
	        "stockid"=>$value['stockid'],
	        "num"=>$value['num'],
	        "send_num"=>$value['num'],
	        "origin_price"=>$value['origin_price'],
	        "addtime"=>date("Y-m-d H:i:s"),
	        "updatetime"=>date("Y-m-d H:i:s"),
	        ];
	        $ordBn[]=$saleBn;
        }

        return self::name("sale_info")->insertAll($ordBn);
    }
	/**
	* @param string $returnCode
	* @param int $salebnid
	* @param int $num
	* @param int $type
	 * @return bool
	* @throws \think\Exception
	 */
	static function ReturnBn(string $returnCode,int $salebnid,int $num,int $type=1){
    	$sabn=self::name("sale_info")->where(['id'=>$salebnid])->findOrEmpty()->toArray();
    	if(empty($sabn))throw new Exception("未找到Bn订单数据",1006);
    	$return=[
    		"returnCode"=>$returnCode,
    	    "type"=>$type,
    	    "orderCode"=>$sabn['orderCode'],
    	    "bnCode"=>$sabn['bnCode'],
    	    "origin_price"=>$sabn['origin_price'],
    	    "num"=>$num,
    	    "addtime"=>date("Y-m-d H:i:s")
    	    ];
    	return self::name("return_info")->insert($return);
    }
	/**  调拨专用 需要注意bn总数变化
	* @param int $stockid 库存id
	* @param string $bnCode bn编号
	* @param int $num  库存数量
	* @param int $flag  操作类型 0 添加库存 1 减少库存
	* @param float|int $origin_price  成本价
	 * @return bool
	* @throws \think\Exception
 */
	static function bnStock(int $stockid,string $bnCode,int $num,int $flag=0,float $origin_price=0){
			$stock =self::where(["stockid"=>$stockid,"bnCode"=>$bnCode])->lock(true)->findOrEmpty()->toArray();
			$update=[];
			if($flag==1) {
				if(empty($stock)|| $stock['balance_num']< $num)
					throw new Exception("bn库存数不足",1006);
				else{
						$update['balance_num']=$stock['balance_num']-$num;
						$update['total_num']=$stock['total_num']-$num;
						$update['updatetime']=date("Y-m-d H:i:s");
					}
			}else{
				if (empty($stock)){
					$update=[
						"bnCode"=>$bnCode,
						"stockid"=>$stockid,
						"total_num"=>$num,
						"used_num"=>0,
						"balance_num"=>$num,
						"origin_price"=>$origin_price,
						"addtime"=>date("Y-m-d H:i:s"),
						"updatetime"=>date("Y-m-d H:i:s")
						];
				}else{
						$update['balance_num']=$stock['balance_num']+$num;
						$update['total_num']=$stock['total_num']+$num;
						$update['updatetime']=date("Y-m-d H:i:s");
				}
			}

			return	empty($stock)? self::insert($update): self::update($update,$stock)->getNumRows();
	}
	/**
    退货退到其他仓库的话 原仓库批次总数 - 退货数量
	* @param $stockid 退货仓库
	* @param $bnCode bn批次编号
	* @param $num 退货数量
	* @param $origin_stockid 原仓库
	 * @return int
	* @throws \think\Exception
	 */
	static function ReturnAdd(int $stockid,string $bnCode,int $num,int $origin_stockid){
		$origin = self::where(["stockid"=>$origin_stockid,"bnCode"=>$bnCode])->findOrEmpty()->toArray();
		if($stockid!=$origin_stockid){
			if(empty($origin))throw new Exception("未找到Bn订单数据",1006);
			$temp['total_num'] =$origin['total_num'] -$num;
			$temp['used_num'] =$origin['used_num'] -$num;
			$temp['updatetime'] =date("Y-m-d H:i:s");
			self::update($temp,$origin);
		}
		$stock = self::where(["stockid"=>$stockid,"bnCode"=>$bnCode])->findOrEmpty()->toArray();
		if(empty($stock)){
			$update=[
						"bnCode"=>makeNo("BN"),
						"stockid"=>$stockid,
						"total_num"=>$num,
						"used_num"=>0,
						"balance_num"=>$num,
						"origin_price"=>$origin['origin_price'],
						"addtime"=>date("Y-m-d H:i:s"),
						"updatetime"=>date("Y-m-d H:i:s")
						];
			$result= self::insert($update);
		}else{
						$update['balance_num']=$stock['balance_num']+$num;
						$stockid!=$origin_stockid ? $update['total_num']=$stock['total_num']+$num:$update['used_num']=$stock['used_num']-$num;
						$update['updatetime']=date("Y-m-d H:i:s");
						$result=self::update($update,$stock)->getNumRows();
		}
		return $result;
	}
	/**分单分配bn号
	* @param string $childCode 分单编号
	* @param int $stockid 库存id
	 */
	static function ChildAddBn(string $childCode='',int $stockid=0){
		$child = OrderOutChild::where(["outChildCode" => $childCode, "is_del" => 0])->findOrEmpty()->toArray();
		if(empty($child))throw new Exception("未找到工单数据",1006);
		$bnArr=self::SaleBn($stockid,intval($child['num']));
        if(empty($bnArr)) throw new Exception("未找到Bn库存数据",1006);
        $ordBn=[];
        foreach ($bnArr as $value){
	        $saleBn=[
	        "orderCode"=>$child['orderCode'],
	        "outCode"=>$child['outCode'],
	        "childCode"=>$childCode,
	        "bnCode"=>$value['bnCode'],
	        "num"=>$value['num'],
	        "total_bn_num"=>$value['num'],
	        "origin_price"=>$value['origin_price'],
	        "addtime"=>date("Y-m-d H:i:s"),
	        "updatetime"=>date("Y-m-d H:i:s"),
	        ];
	        $ordBn[]=$saleBn;
        }
		return self::name("child_bn")->insertAll($ordBn);
	}
	/**
	* @param $childCode
	* @param $stockid
	* @param int $num
	 * @return bool
	* @throws \think\Exception
	* @throws \think\db\exception\DataNotFoundException
	* @throws \think\db\exception\DbException
	* @throws \think\db\exception\ModelNotFoundException
	 */
	static function ChildReturnBn($childCode,$stockid,$num=0){

		$childBN =  self::name("child_bn")->where([["childCode","=",$childCode],["num",">=",0]])->select()->toArray();
		if(empty($childBN))throw new \Exception("未找到工单库存明细数据",1005);
		foreach ($childBN as $value){
			$bninfo =self::where(["bnCode"=>$value['bnCode'],"stockid"=>$stockid])->findOrEmpty()->toArray();
			if(empty($bninfo))throw new \Exception("未找到库存bn数据",1005);
			$temp=[];
			$bntmp=[];
			$temp['updatetime']=date("Y-m-d H:i:s");
			$bntmp['updatetime']=date("Y-m-d H:i:s");
			if($value["num"]<=$num){
				$temp['num']=0;
				$temp['is_del']=1;
				$bntmp['balance_num']= $bninfo['balance_num']+$value['num'];
				$bntmp['used_num']= $bninfo['used_num']-$value['num'];
				$num -=$value['num'];
			}else{
				$temp['num']=$value['num']-$num;
				$bntmp['balance_num']= $bninfo['balance_num']+$num;
				$bntmp['used_num']= $bninfo['used_num']-$num;
				$num=0;
			}
            $up = self::name("child_bn")->where('id',$value['id'])->update($temp);
            if($up==false)throw new \Exception("工单库存明细更新失败",1005);
			$bnup =self::update($bntmp,$bninfo)->getNumRows();
			if($bnup==false) throw new \Exception("库存bn更新失败",1005);
			if($num==0) break;
		}
		return true;
	}
}