<?php
class voucherAction extends action
{
	public $object;
	public $logic;
    function __construct(){
        parent::__construct();
		$this->mod = new voucherMod();
		$this->object = new objectMod();
		$this->logic = new logicMod();
    }

    function __destruct(){
    }

	/**
	 * Method 列表数据
	 */
    function list(){
		$where = '';
		$filters = $_REQUEST['filters'];
		if(empty($filters)){
			$input = file_get_contents('php://input');
			$params = json_decode($input,true);
			$filters = $params['filters'];
		}
		if($filters){
			$groups = json_decode(htmlspecialchars_decode($filters),true);
			$where = $this->groups2sql($groups,function($field,$op,$data)use($scheCols){
                //if(in_array($field,['subjectText','depText','staffText','clientText',])){
				if (in_array($field, ['subjectText', 'depText', 'staffText',])) {
                    $rule = [
                        'subjectText'=>['findField'=>'v_subject',  'targetID'=>200, 'targetField'=>'getObjectChilds(o_id)'],
                        'depText'=>    ['findField'=>'v_object_1', 'targetID'=>1  , 'targetField'=>'o_id'],
                        'staffText'=>  ['findField'=>'v_object_2', 'targetID'=>2  , 'targetField'=>'o_id'],
                        //'clientText'=> ['findField'=>'v_object_4', 'targetID'=>4  , 'targetField'=>'o_id'],
                    ];
                    $rootNode = $this->mod->dbRead->Row("SELECT o_lft,o_rgt FROM `object` WHERE o_id=".$rule[$field]['targetID']);
                    $arr = $this->mod->dbRead->Table("SELECT ".$rule[$field]['targetField']." ids FROM `object` 
                                WHERE o_lft>=".$rootNode['o_lft']." AND o_rgt<=".$rootNode['o_rgt']." AND o_keyword like '%".trim($data)."%'");
                    if($arr){
                        $field = $rule[$field]['findField'];
                        $op = 'in';
                        $data = implode(',', array_column($arr,'ids'));
                    }else{
                        $field = '1'; $op = 'eq'; $data = '0';
                    }
				} else if ($field == 'cycleseq') {
					$field = 'CONCAT(v_cycle,"-",v_seq)';
				} else if ($field == 'clientText') {
					$field = 'v_client';
				} else if ($field == 'update_time' || $field == 'create_time') {
					$field = 'MID(' . $field .', 1, 16)';
					$data = substr($data, 0, 16);
				} else if ($field == 'select') {
					$op == false;
				}
				return ['field'=>$field,'op'=>$op,'data'=>$data];
			});

		}
		if($_POST['sidx']=='cycleseq') $_POST['sidx']='v_cycle,v_seq';
        $this->mod->isForm = !empty($_REQUEST['form']); 
		$data = $this->mod->list($where, $_POST['page'], $_POST['rows'], $_POST['sidx'], $_POST['sord']);
		foreach($data['rows'] as $k=>$row){
			$row['subjectText'] = $row['subjectText'];
			if(empty($_REQUEST['form'])){
				$row['v_j'] = numformat($row['v_j']);
				$row['v_d'] = numformat($row['v_d']);
			}
			$row['update_time'] = substr($row['update_time'], 0, -3);
			$row['create_time'] = substr($row['create_time'], 0, -3);
			$row['select'] = $row['cycleseq'];
			$data['rows'][$k] = $row;
		}
		echo json_encode($data, JSON_UNESCAPED_UNICODE);
	}
	/**
	 * Method 通过关键字取一行数据
	 */
	function getRowByKey($key){
		$row = $this->mod->getRowByKey('*',$key);
		if($row){
			$this->exitJson(0,$row);
		}else{
			$this->exitJson(2000);
		}
	}

	/**
	 * Method 取下一个序号
	 */
	function netSeq($cycle){
		$max = $this->mod->maxCheckoutCycle();
		if($max>=$cycle){
			$this->exitJson(2003,'当前选择的周期小于已结算周期');
		}else{
			if($seq = $this->mod->getOne("IFNULL(MAX(v_seq)+1,1)",sprintf("v_cycle=%s", $cycle))){
				$this->exitJson(0,$seq);
			}else{
				$this->exitJson(2000);
			}
		}
	}
	/**
	 * Method 修改操作
	 */
	function edit(){
		$input = file_get_contents('php://input');
		$params = json_decode($input,true);
		//dd($params);
		if(empty($params['date']) || empty($params['cycle'])){
			$this->exitJson(2001,'没有日期');
		}
		if(empty($params['seq'])){
			$this->exitJson(2001,'没有序号');
		}
		//getCycle，getSeq 修改前
		if($this->mod->isCheckout($params["cycle"])){
			$this->exitJson(2003,$params["cycle"].' 已结算,不能再录入');
		}
		$has = $this->mod->getOne('1', sprintf("v_cycle=%s AND v_seq=%s", $params["cycle"],$params["seq"])) ? true : false;
		if($has && ($params['getCycle']!=$params['cycle'] || $params['getSeq']!=$params['seq'])){
			$this->exitJson(2002,$params["cycle"].'.'.$params["seq"].'号 本期凭证号已经被使用');
		}
		$total_j = 0;
		$total_d = 0;
		$idArr = null;
		$dbRows = [];
		foreach($params['data'] as $row){
			if(empty(trim($row['subjectText']))){
				$this->exitJson(2001,'科目不完整');
			}else if(empty($row['v_j']) && empty($row['v_d'])){
				$this->exitJson(2001,'金额不完整');
			}
			$total_j = $total_j + $row['v_j'] * 1;
			$total_d = $total_d + $row['v_d'] * 1;
			if(!empty($row['v_id'])){
				$idArr[] = $row['v_id'];
			}
			if($t = $this->object->getRowByFullName(200,$row['subjectText'])){
				$v_subject = $t['o_id'];
				//取余额方向
				$v_direction = 0;
				if($one = $this->mod->getOneSelectTable('object_ext_val','oev_int',sprintf("oev_o_id=%s AND oev_oe_id=2",$v_subject))){
					$v_direction = ($one==203) ? 1 : 0;
				}
			}else{
				$this->exitJson(2001,'找不到科目[ '. $row['subjectText'] .' ]');
			}
			if(trim($row['depText'])!=''){
				if($row['depText'] && $t = $this->object->getRowByFullName(1,$row['depText'])){
					$v_object_1 = $t['o_id'];
				}else{
					$this->exitJson(2001,'找不到部门[ '. $row['depText'] .' ]');
				}
			}else{
				$v_object_1 = '';
			}
			if(trim($row['staffText'])!=''){
				if($t = $this->object->getRowByFullName(2,$row['staffText'])){
					$v_object_2 = $t['o_id'];
				}else{
					$this->exitJson(2001,'找不到职员[ '. $row['staffText'] .' ]');
				}
			}else{
				$v_object_2 = '';
			}
			/*
			if(trim($row['clientText'])!=''){
				if($t = $this->object->getRowByFullName(4,$row['clientText'])){
					$v_object_4 = $t['o_id'];
				}else{
					$this->exitJson(2001,'找不到客户[ '. $row['clientText'] .' ]');
				}
			}*/
			if($extlist = $this->object->getExtvalList($v_subject)){
				if(isset($extlist[3])){
					$t = $extlist[3]['value'];
					if(in_array(1,$t) && empty($v_object_1)){
						$this->exitJson(2001,$row['subjectText'].' 核算对象不完整, 缺失 [ 部门 ]');
					}
					if(in_array(2,$t) && empty($v_object_2)){
						$this->exitJson(2001,$row['subjectText'].' 核算对象不完整, 缺失 [ 职员 ]');
					}
					/*
					if(in_array(4,$t) && empty($v_object_4)){
						$this->exitJson(2001,$row['subjectText'].' 核算对象不完整, 缺失 [ 客户 ]');
					}*/
				}
			}else{
				$v_object_2 = '';
			}
			if($row['v_id']==0)    $row['v_id'] = '';
			if(empty($row['v_j'])) $row['v_j']  = '0';
			if(empty($row['v_d'])) $row['v_d']  = '0';
			$dbRows[] = [
				'v_id'=>          $row['v_id'],
				'v_cycle'=>       $params['cycle'],
				'v_seq'=>         $params['seq'],
				'v_year'=>        substr($params['cycle'],0,4),
				'v_date'=>        $params['date'],
				'v_j'=>           str_replace(',','',$row['v_j']),
				'v_d'=>           str_replace(',','',$row['v_d']),
				'v_direction'=>   $v_direction,
				'v_client' =>     $row['clientText'] ?: '',
				'v_summary' =>    $row['v_summary'],
				'v_state'=>       $params['state'],
				'v_subject'=>     $v_subject,
				'v_object_1'=>    $v_object_1,
				'v_object_2'=>    $v_object_2,
				//'v_object_4'=>    $v_object_4
			];
		}
		if($total_j==0){
			$this->exitJson(2001,'借方金额不能为0');
		}
		if($total_j.'' != $total_d.''){
			$this->exitJson(2001,'借贷方金额不平');
		}

		$idArr = null;
		foreach($params['data'] as $k=>$row){
			$params['data'][$k]['v_year'] = substr($row['v_cycle'],0,4);
			if(!empty($row['v_id'])){
				$idArr[] = $row['v_id'];
			}
		}
		$ids = '0';
		if($idArr) $ids = implode(',',$idArr);
		//getCycle
		$this->mod->Begin();
		if($params['getCycle'] !='' && $params['getSeq'] !='' && $params['getCycle']!=$params['cycle']){
			//更换周期，删除当前凭证原记录
			$this->mod->deleteRows( sprintf("v_cycle=%s AND v_seq=%s", $params["getCycle"],$params["getSeq"]) );
		}else{
			//删除当前凭证下没有提交的 ID 记录
			$this->mod->deleteRows( sprintf("v_cycle=%s AND v_seq=%s AND v_id not in ($ids)", $params["cycle"],$params["seq"], $ids) );
		}
		foreach($dbRows as $row){
			if(!empty($row['v_id']) && $this->mod->getOneByKey('1',$row['v_id'])){ 
				$this->mod->setRowByKey($row,$row['v_id']); //如果记录存在
			}else{
				$this->mod->addRow($row); //添加
			}
		}
		$dbOk = $this->mod->End();
		if($dbOk){
			$this->exitJson(0);
		}else{
			$this->exitJson(2000);
		}
	}
	/**
	 * Method 删除操作
	 */
	function delete()
	{
		$input = file_get_contents('php://input');
		$params = json_decode($input, true);
		$cycle = $params['cycle'];
		$seq = $params['seq'];
		if (empty($cycle) || empty($seq)) {
			$this->exitJson(2001);
		}
		if ($this->mod->isCheckout($cycle)) {
			$this->exitJson(2003, $cycle . ' 已结算,不能删除');
		}
		if ($this->mod->isExamine($cycle, $seq)) {
			$this->exitJson(2004, $cycle . '.' . $seq . ' 已审核,不能删除');
		}
		$this->mod->Begin();
		$this->mod->deleteRows(sprintf("v_cycle=%s AND v_seq=%s", $cycle, $seq));
		$dbOk = $this->mod->End();
		if ($dbOk) {
			$this->exitJson(0);
		} else {
			$this->exitJson(2000);
		}
	}
	/**
	 * 选择批量操作
	 */
	function opSelectLots()
	{
		$input = file_get_contents('php://input');
		$params = json_decode($input, true);
		$type = $params['type'];
		$selectList = $params['selectList'];
		$cycleBegin = 0;
		$items = [];
		foreach($selectList as $v){
			list($cycle, $seq) = explode('-', $v);
			$cycle = ('20' . $cycle) * 1;
			if ($cycleBegin == 0 || $cycle < $cycleBegin) {
				$cycleBegin = $cycle;
			}
			$items[] = ['v_cycle'=>$cycle, 'v_seq' => $seq];
		}
		if ($this->mod->isCheckout($cycleBegin)) {
			$this->exitJson(2003, $cycleBegin . ' 已结算,不能操作');
		}
		$this->mod->Begin();
		foreach ($items as $item) {
			if ($type == '删除') {
				$sql = sprintf("DELETE FROM voucher WHERE v_state<>1 AND v_cycle='%s' AND v_seq='%s'", $item['v_cycle'], $item['v_seq']);
				$this->mod->doQuery($sql);
			} else if ($type == '审核') {
				$q = (new sqler($this->logic->db))->table('voucher')
					->where('v_state', 0)
					->and('v_cycle', $item['v_cycle'])
					->and('v_seq', $item['v_seq'])
					->order('v_id');
				$groups = $q->map(['v_cycle','v_seq'],true)->all();
				foreach($groups as $key=>$rows){
					$msg = $this->isValid($rows);
					if($msg!==true){
						$this->exitJson(2003,  str_replace('.', '-', $key) . ' 凭证数据不完整, '. $msg);
					}
				}
				$sql = sprintf("UPDATE voucher SET v_state=1 WHERE v_state=0 AND v_cycle='%s' AND v_seq='%s'", $item['v_cycle'], $item['v_seq']);
				$this->mod->doQuery($sql);
			} else if ($type == '反审核') {
				$sql = sprintf("UPDATE voucher SET v_state=0 WHERE v_state=1 AND v_cycle='%s' AND v_seq='%s'", $item['v_cycle'], $item['v_seq']);
				$this->mod->doQuery($sql);
			}
		}
		$dbOk = $this->mod->End();
		if ($dbOk) {
			$this->exitJson(0);
		} else {
			$this->exitJson(2000);
		}
		
	}

	/**
	 * 批量操作
	 */
	function opLots()
	{
		$input = file_get_contents('php://input');
		$params = json_decode($input, true);
		$type = $params['type'];
		//$opLotsBeginCycle = $params['opLotsBeginCycle'];
		//$opLotsEndCycle = $params['opLotsEndCycle'];
		$opLotsBeginDate = $params['opLotsBeginDate'];
		$opLotsEndDate = $params['opLotsEndDate'];

		$opLotsBeginTime = strtotime($opLotsBeginDate);
		$opLotsEndTime = strtotime($opLotsEndDate);
		$opLotsBeginDate = date('Y-m-d', $opLotsBeginTime);
		$opLotsEndDate = date('Y-m-d', $opLotsEndTime);
		$cycleBegin = date('Ym', $opLotsBeginTime);
		$cycleEnd = date('Ym', $opLotsEndTime);
		if (empty($cycleBegin) || empty($cycleEnd)) {
			$this->exitJson(2001);
		}
		if ($this->mod->isCheckout($cycleBegin)) {
			$this->exitJson(2003, $cycleBegin . ' 已结算,不能操作');
		}
		if ($this->mod->isCheckout($cycleEnd)) {
			$this->exitJson(2003, $cycleEnd . ' 已结算,不能操作');
		}
		$this->mod->Begin();
		if ($type == '删除') {
			$sql = sprintf("DELETE FROM voucher WHERE v_state<>1 AND v_date>='%s' AND v_date<='%s'", $opLotsBeginDate, $opLotsEndDate);
			$this->mod->doQuery($sql);
		} else if ($type == '审核') {
			$q = (new sqler($this->logic->db))->table('voucher')
				->where('v_state', 0)
				->and('v_date{>=}', $opLotsBeginDate)
				->and('v_date{<=}', $opLotsEndDate)
				->order('v_id');
			$groups = $q->map(['v_cycle','v_seq'],true)->all();
			foreach($groups as $key=>$rows){
				$msg = $this->isValid($rows);
				if($msg!==true){
					$this->exitJson(2003,  str_replace('.', '-', $key) . ' 凭证数据不完整, '. $msg);
				}
			}
			$sql = sprintf("UPDATE voucher SET v_state=1 WHERE v_state=0 AND v_date>='%s' AND v_date<='%s'", $opLotsBeginDate, $opLotsEndDate);
			$this->mod->doQuery($sql);
		} else if ($type == '反审核') {
			$sql = sprintf("UPDATE voucher SET v_state=0 WHERE v_state=1 AND v_date>='%s' AND v_date<='%s'", $opLotsBeginDate, $opLotsEndDate);
			$this->mod->doQuery($sql);
		}
		$dbOk = $this->mod->End();
		if ($dbOk) {
			$this->exitJson(0);
		} else {
			$this->exitJson(2000);
		}

	}

	function isValid($rows){
		$j = 0;
		$d = 0;
		$summary = '';
		foreach($rows as $k=>$row){
			if($k==0) $summary = trim($row['v_summary']);
			$j += $row['v_j'];
			$d += $row['v_d'];
			if (empty($row['v_subject'])) {
				return '科目不能为空';
			}
			if ($extlist = $this->object->getExtvalList($row['v_subject'])) {
				if (isset($extlist[3])) {
					$t = $extlist[3]['value'];
					if (in_array(1, $t) && empty($row['v_object_1'])) {
						$o_name = (new sqler($this->logic->db))->table('object')->field('o_name')->and('o_id', $row['v_subject'])->one();
						return $o_name.' 核算对象不完整, 缺失 [ 部门 ]';
					}
					if (in_array(2, $t) && empty($row['v_object_2'])) {
						$o_name = (new sqler($this->logic->db))->table('object')->field('o_name')->and('o_id', $row['v_subject'])->one();
						return $o_name . ' 核算对象不完整, 缺失 [ 职员 ]';
					}
				}
			}
		}
		if ($j == 0) {
			return '借方金额不能为0';
		}
		if ($j != $d) {
			return '借贷方金额不平';
		}
		if ($summary == '') {
			return '第一条摘要不能为空';
		}
		return true;
	}
}