<?php


namespace app\cxinv\controller;


use app\cxinv\model\InvoiceOrder;
use app\cxinv\model\PayInvoice;
use app\cxinv\model\PayReturn;
use app\cxinv\model\RoleAction;
use app\user\model\AccountCompany;
use think\App;
use think\facade\Validate;
class Payinv extends Base{
    public function __construct(App $app) {
        parent::__construct($app);
        $this->model =new PayInvoice();
    }

    public function create(){
        $params = $this->request->param(["InvCode"=>""],"post","trim");
        $valid= Validate::rule([
            'InvCode' => 'require|max:255'
        ]);
        if (!$valid->check($params))return error($valid->getError());
        $isT = $this->model->where(["payNo"=>$params['InvCode'],"status"=>[1,2,3,4]])->findOrEmpty();
        if (!$isT->isEmpty())return error("该发票单号已存在");
        $invoice = \app\cxinv\model\Invoice::where("InvCode",$params['InvCode'])->findOrEmpty();
        if ($invoice->isEmpty())return error("该发票单号不存在");
        if ($invoice->status!=2)return error("该发票单号状态不正确");
         $hpNo=makeNo('hp');
         $data=[
                'payNo'=>$params['InvCode'],
                'hpNo'=>$hpNo,
                'apply_id'=>$this->uid,
                'apply_name'=>$this->uname,
                'inv_fee'=> $invoice->invoice_total, //核算金额
                'inv_subtotal_amount'=> $invoice->invoice_subtotal,//票面金额
                'inv_amount'=> $invoice->invoice_total, //票面金额
                'invType'=>4,//发票申请类型 1 手工添加 2 ocr识别 3 金税扫描 4 发票池
                'invoiceType'=>$invoice->invoice_type,
                'inv_img'=>'',
                'invName'=>'',
                'invStatus'=>1,
                'invoiceNumber'=>$invoice->invoice_number,
                'invoiceCode'=>$invoice->invoice_code,
                'status'=>11,//待关联订单
                'checkNumber'=>$invoice->check_code,
                'open_time'=>$invoice->open_date,
                'addtime'=>date('Y-m-d H:i:s'),
                'updatetime'=>date('Y-m-d H:i:s')
            ];
            $this->model->startTrans();
            try{
                $res=$this->model->save($data);
                if(!$res) throw new \Exception("添加失败");
                $invoice->status=3;
                $up=$invoice->save();
                if(!$up) throw new \Exception("更新发票状态失败");
                $this->model->commit();
            } catch (\Exception $e){
                $this->model->rollback();
                return error($e->getMessage());
            }
            return success("添加成功");
    }

    public function list(){
        $params = $this->request->param(["page"=>1,"size"=>20,"status"=>"","payNo"=>"","apply_id"=>"","companyNo"=>"",
        "supplierNo"=>"","invoiceType"=>"",'relaComNo'=>'', "open_time"=>"", "invoiceNumber"=>"","start"=>"","end"=>"","hpNo"=>""]);
        $where=[["a.is_del","=",0],["invType","=",4]];
         $check =RoleAction::checkRole($this->roleid,[82,120]);
        if($check){
            $where[]=['a.apply_id','=',$this->uid];
        }
        if ($params['status']!='')$where[]=['a.status','=',$params['status']];
        if ($params['payNo']!='')$where[]=['a.payNo','like','%'.$params['payNo'].'%'];
        if ($params['apply_id']!='')$where[]=['a.apply_id','=',$params['apply_id']];
        if ($params['companyNo']!='')$where[]=['b.companyNo','=',$params['companyNo']];
        if ($params['supplierNo']!='')$where[]=['b.supplierNo','=',$params['supplierNo']];
        if ($params['invoiceType']!='')$where[]=['a.invoiceType','=',$params['invoiceType']];
        if ($params['open_time']!='')$where[]=['a.open_time','=',$params['open_time']];
        if ($params['invoiceNumber']!='')$where[]=['a.invoiceNumber','like','%'.$params['invoiceNumber'].'%'];
        if ($params['start']!='' && $params['end']!=''){
            $where[]=['a.addtime','between',[startTime($params['start']),endTime($params['end'])]];
        }
        if ($params['hpNo']!='')$where[]=['a.hpNo','like','%'.$params['hpNo'].'%'];
        if($params['relaComNo']!='') $where[]=['b.companyNo|b.supplierNo','=',$params['relaComNo']];
        $list = $this->model->alias('a')
            ->join('invoice b','a.payNo=b.InvCode')
            ->field('a.*,b.supplierNo,b.supplierName,b.companyName,b.companyNo')
            ->where($where)
            ->order('a.id desc')
            ->paginate(["list_rows"=>$params['size'],"page"=>$params['page']]);

        foreach ($list->items() as $k=>&$v){
              $v['has_account'] = AccountCompany::SupplierHasAcount($v['supplierNo']);
              $v['invoiceType_cn'] = \app\cxinv\model\Invoice::$invoiceType[$v['invoiceType']]??"";
              $v['invStatus_cn'] =\app\cxinv\model\Invoice::$invStatus[$v['invStatus']]??'';
        }

        return success("获取成功",["list"=>$list->items(),"count"=>$list->total()]);
    }

    public function info(){
        $params = $this->request->param(["hpNo"=>""],"post","trim");
        $valid= Validate::rule([
            'hpNo' => 'require|max:255'
        ]);
        if (!$valid->check($params))return error($valid->getError());
        $info = $this->model->alias('a')
                    ->join('invoice b','a.payNo=b.InvCode')
                    ->field('a.*,b.supplierNo,b.supplierName,b.companyName,b.companyNo')
                    ->where(["a.hpNo"=>$params['hpNo']])->findOrEmpty();
        if ($info->isEmpty())return error("该数据不存在");
        $info['invoiceType_cn'] = \app\cxinv\model\Invoice::$invoiceType[$info['invoiceType']]??"";
        $info['invStatus_cn'] =\app\cxinv\model\Invoice::$invStatus[$info['invStatus']]??'';
        return success("获取成功",$info);
    }
     /** 1待系统验证 2 买方公司审核 3带买方公司认证 4 认证成功 5验证失败 6买方审核驳回 7 认证失败 8 回票流程终止 9 验证超次数 10 回票已退
      * 11 待关联订单 12 订单关联完毕待财务审核 13 订单关联完毕财务驳回 14 待确认发票明细
      **/
    public function status(){
        $params = $this->request->param(["hpNo"=>"","status"=>"","remark"=>"",'ItemRemark'=>[]]);
        $valid= Validate::rule([
            'hpNo' => 'require|max:255',
            "status"=>"require|number|in:1,2,3,4,6,7,8,11,13",
            "remark"=>"max:255",
            'ItemRemark'=>'array'
        ]);
        if (!$valid->check($params))return error($valid->getError());
        $info = $this->model->where(["hpNo"=>$params['hpNo']])->findOrEmpty();
        if ($info->isEmpty())return error("该数据不存在");
        if($info->invType!=4) return error("该数据不是发票池数据");
        $invoice = \app\cxinv\model\Invoice::where(["InvCode"=>$info['payNo']])->findOrEmpty();
        if ($invoice->isEmpty())return error("该发票池数据不存在");
        if($invoice->status!=3) return error("该发票池数据状态不正确");
        if($params['status']==3) $info->check_time= date('Y-m-d H:i:s');
        if($params['status']==11 && $info->status==14){
            $itemLow = InvoiceItem::where(['invoiceCode'=>$params['hpNo']])->where([["amount","<",0]])->findOrEmpty();
            if (!$itemLow->isEmpty()) return error("存在负数明细,请先确认明细");
        }
        $info->status=$params['status'];
        $info->remark=$params['remark'];
        $this->model->startTrans();
        try{
            $save= $info->save();
            if ($save===false) throw new \Exception("修改失败");
            if (!empty($params['ItemRemark']) &&$params['status']==3){
                 (new InvoiceOrder)->saveAll($params['ItemRemark']);
            }
            $this->model->commit();
        }catch (\Exception $e){
            $this->model->rollback();
            return error($e->getMessage());
        }
        return success("修改成功");
    }
        /**批量上传待认证发票
    * @param hpNo array 回票申请编号集合 必传
    * @param relaComNo string 业务公司编号  企业账户
    * @param companyNo string 业务公司编号 超管账户
	* @return \think\response\Json|void
	*/

    //回票申请批量认证
    public function hpBatchImport()
    {
        $post = $this->request->only(['list' => [], 'relaComNo' => '', 'companyNo' => ''], 'post');
        $valid = Validate::rule([
            'list|回票申请编号集合' => 'require|array|max:100',
            'relaComNo|关联公司' => 'requireWithout:companyNo|max:255',
            'companyNo|公司编号' => 'requireWithout:relaComNo|max:255',
        ]);
        if ($valid->check($post) == false) return error($valid->getError());
        $companyNo = $post['relaComNo'] ?: $post['companyNo'];

        $val_hpNo = Validate::rule([
            'hpNo|回票申请编号' => 'require',
            'status|审核状态' => 'require|number|in:4,7',
            'remark|审核备注' => 'requireIf:status,7|max:255'
        ]);
		$unique=[];
        foreach ($post['list'] as $item) {
            if (!$val_hpNo->check($item)) return error($val_hpNo->getError());
            if(in_array($item['hpNo'],$unique))return error("{$item['hpNo']} 发票重复提交");
            $unique[]=$item['hpNo'];
        }
        $payArr = $this->model
                    ->alias('a')
                    ->leftJoin('invoice b', 'a.payNo=b.InvCode')
                    ->where(['a.is_del' => 0])
                    ->whereIn('a.hpNo', $unique)
                    ->column('a.id,a.payNo,a.hpNo,a.invType,a.status,b.companyNo,a.remark', 'a.hpNo');
        if (empty($payArr)) return error("没有需要认证的发票");
        $this->model->startTrans();
        try {
            $saveAll=[];
            foreach ($post['list'] as $val) {
                if (!$val_hpNo->check($val)) throw new \Exception($val_hpNo->getError());
                if (!isset($payArr[$val['hpNo']])) throw new \Exception("{$val['hpNo']}记录不存在");
                $value = $payArr[$val['hpNo']];
				$payinfo =\app\cxinv\model\Invoice::where(['InvCode'=>$value['payNo'],'status'=>3])->findOrEmpty();
				if(empty($payinfo)) throw new \Exception("{$value['hpNo']}发票信息有误");
                if ($payinfo['companyNo'] == '') throw new \Exception("{$value['hpNo']}发票业务公司信息有误");
                if ($payinfo['companyNo'] != $companyNo) throw new \Exception("{$value['hpNo']}不属于当前业务公司发票");
                if ($value['status'] != '3') throw new \Exception("{$value['hpNo']}状态有误");
                $value['status'] = $val['status'];
                if ($val['remark'] != '') {
                    $value['remark'] =$val['remark'];
                }
                $saveAll[]=$value;
            }
            $this->model->saveAll($saveAll);
           $this->model->commit();
         } catch (\Exception $e) {
           $this->model->rollback();
            return error( $e->getMessage());
        }
        return success('回票申请认证成功');
    }
   public function Back(){
         $param= $this->request->param(['hpNo'=>'','reason'=>''],'post','trim');
         $valide=Validate::rule([
             'hpNo|回票编号'=>'require|max:255',
             'reason|备注'=>'require|max:255'
         ]);
         if(!$valide->check($param)) return error($valide->getError());
         $info=$this->model->where('hpNo',$param['hpNo'])->findOrEmpty();
         if($info->isEmpty()) return error('回票编号不存在');
         if ($info->invType!=4) return error('该数据不是发票池数据');
         $invoice = \app\cxinv\model\Invoice::where(['InvCode'=>$info['payNo']])->findOrEmpty();
        if ($this->level == 2) {
		    //判断是否开通供应商账号
		    $rebool= AccountCompany::SupplierHasAcount($invoice->supplierNo);
		    if ($rebool) return error( '该供应商已经开通账号,不允许当前账号操作');
	    }
        if ($info->status!=4) return error('回票信息流程未完成');
        $isr = PayReturn::where(['orderCode'=>$param['hpNo'],'status'=>[1,2],'is_del'=>0])->findOrEmpty();
        if (!$isr->isEmpty()) return error('该订单已申请退票,不允许重复申请');
        $returnCode =makeNo('RP');
		$data = [
			'returnCode'=>$returnCode,
			'returnType'=>3,
			'payNo'=>$info['payNo'],
			'orderCode'=>$param['hpNo'],
			'reason'=>$param['reason'],
			'returnImg'=>'',
			'remark'=>'',
			'status'=>1,
			'apply_id'=>$this->uid,
			'apply_name'=>$this->uname,
			'is_del'=>0,
			'addtime'=>date('Y-m-d H:i:s'),
			'updatetime'=>date('Y-m-d H:i:s'),
		];
		$ce= PayReturn::create($data);
		if (!$ce) return error('申请退票创建失败');
		return success('申请退票创建成功');
    }
    public function BackList(){
      	$param =$this->request->only(['relaComNo'=>'','companyNo'=>'','supplierNo'=>'','start'=>'','end'=>'','returnCode'=>'',
		'status'=>'','InvCode'=>'','hpNo'=>'','page'=>1,'size'=>15],'post','trim');
      	$condition=[['a.is_del','=',0],['a.returnType','=',3]];
      	$check = RoleAction::checkRole($this->roleid,[132,130]);
      	if($check) $condition[]=['a.apply_id','=',$this->uid];
      	if($param['relaComNo']!='') $condition[]=['c.companyNo|c.supplierNo','=',$param['relaComNo']];
		if($param['companyNo']!='') $condition[]=['c.companyNo','=',$param['companyNo']];
		if($param['supplierNo']!='') $condition[]=['c.supplierNo','=',$param['supplierNo']];
		if($param['start']!='') $condition[]=['a.addtime','>=',date('Y-m-d H:i:s',strtotime($param['start']))];
		if($param['end']!='') $condition[]=['a.addtime','<=',date('Y-m-d 23:59:59',strtotime($param['end']))];
		if($param['status']!='') $condition[]=['a.status','=',$param['status']];
		if($param['hpNo']!='') $condition[]=['a.orderCode','=',$param['hpNo']];
		if($param['InvCode']!='') $condition[]=['c.InvCode','=',$param['InvCode']];
		if($param['returnCode']!='') $condition[]=['a.returnCode','=',$param['returnCode']];
		$list= PayReturn::alias('a')
		->join('pay_invoice b','a.orderCode=b.hpNo','left')
		->join('invoice c','b.payNo=c.InvCode','left')
		->where($condition)
		->field('a.*,c.InvCode,c.supplierNo,c.supplierName,c.companyNo,c.companyName,c.invoice_total,c.invoice_subtotal,c.open_date,c.invoice_code,c.invoice_number')
		->order('a.id desc')
		->paginate(['list_row'=>$param['size'],'page'=>$param['page']]);
		foreach ($list as $k=>&$v){
            $v['has_account'] = AccountCompany::SupplierHasAcount($v['supplierNo']);
		}
        return success('获取成功',['list'=>$list->items(),'count'=>$list->total()]);
    }
    public function BackInfo(){
        $param =$this->request->only(['returnCode'=>''],'post','trim');
        $valide=Validate::rule([
				'returnCode|退票申请编号'=>'require|max:255',
			]);
        if(!$valide->check($param))return error($valide->getError());
        $info= PayReturn::alias('a')
        		->join('pay_invoice b','a.orderCode=b.hpNo','left')
        		->join('invoice c','b.payNo=c.InvCode','left')
        		->where(['returnCode'=>$param['returnCode'],'returnType'=>3,'a.is_del'=>0])
        		->field('a.*,c.InvCode,c.supplierNo,c.supplierName,c.companyNo,c.companyName,c.invoice_total,c.invoice_subtotal,c.open_date,c.invoice_code,c.invoice_number')
            ->findOrEmpty();
        if($info->isEmpty()) return error('退票申请编号不存在');
        $info['invoice'] = $this->model->with(['items'])->where(['hpNo'=>$info->orderCode])->findOrEmpty();
        return success('获取成功',$info);
    }
    public function BackStatus(){
      $param =$this->request->only(['returnCode'=>'','status'=>'','remark'=>'','returnImg'=>''],'post','trim');
      $valide=Validate::rule([
				'returnCode|退票申请编号'=>'require|max:255',
				'status|状态'=>'require|number|in:1,2,3',
			]);
      if(!$valide->check($param))return error($valide->getError());
      $info= PayReturn::where(['returnCode'=>$param['returnCode'],'returnType'=>3,'is_del'=>0])->findOrEmpty();
      if($info->isEmpty()) return error('退票申请编号不存在');
      $invoice = $this->model->where(['hpNo'=>$info['orderCode'],'is_del'=>0])->findOrEmpty();
      if($invoice->isEmpty()) return error('发票信息不存在');
      if($invoice->status!=4) return error('发票申请状态不允许退票');
      $info->status=2;
      $info->remark=$param['remark'];
      $info->returnImg=$param['returnImg'];
      $info->updatetime=date('Y-m-d H:i:s');
      $this->model->startTrans();
      try{
          $up=$info->save();
          if(!$up) throw new \Exception('审批失败');
          if($param['status']==2){
              $invoice->status=10;
              $invoice->updatetime=date('Y-m-d H:i:s');
              $up2=$invoice->save();
              if(!$up2) throw new \Exception('审批失败');
          }
          $this->model->commit();
      }catch (\Exception $e){
          $this->model->rollback();
          return error('审批失败');
      }
       return success('审批成功');
    }

}