<?php
/**
 * Class voucher model
 */
class voucherMod extends mod{
    public $isForm = false;
	function __construct(){
		$e = require(mvc::$cfg['ROOT'].'mod/element/voucher.php');
		parent::__construct($e);
    }
	/**
	 * Method 列表数据
	 * @param string $where 查询sql条件
	 * @param int $page 页码(从1开始)
	 * @param int $pagesize 分页大小
	 * @param string $sidx 排序字段(单个)
	 * @param string $sord 排序方式 asc|desc
	 * @param string $orderby 排序sql(可多个)[优先]
	 * @return array 数据集
	 */
	public function list($where='',$page=0,$pagesize=0,$sidx='',$sord='asc',$orderby=''){
        $sql = $this->e['view'];
		if(trim($where)!='') {
			if(strtolower(substr(trim($where),0,3))!=='and') $where = ' AND ' . $where;
			$sql .= $where;
		}
		if($sidx=='' && $orderby=="") $orderby =  $this->e['order']; //默认排序
		if($orderby!=''){
			$sql.= sprintf(' ORDER BY %s', $orderby);
		}else if($sidx!=''){
			$sql.= sprintf(' ORDER BY %s %s',$sidx,$sord);
		}
		//exit($sql);
		if($page>0 && $pagesize>0){
			$pages = $this->dbRead->PageLimit($sql,$page,$pagesize);
			$sql .= $pages['limit'];
		}
		$rows = $this->dbRead->Table($sql);
        $this->formatRows($rows);
		$footerData=[];
		$data = [
			'page'=> $pages['page'],
			'total'=> $pages['total'],
			'records' => $pages['records'],
			"userdata"=> $footerData,
			'rows' => $rows
		];
		return $data;
	}
	/**
	 * Method 取当前凭证号状态
	 * @return int
	 */
	public function formatRows(&$rows){
        $subjects = [];
        $subjectKeywords = [];
        $objects = [];
		foreach($rows as $row){
            if($row['v_subject'])  $subjects[$row['v_subject']] = '';
            if($row['v_object_1']) $objects[$row['v_object_1']] = '';
            if($row['v_object_2']) $objects[$row['v_object_2']] = '';
            if($row['v_object_4']) $objects[$row['v_object_4']] = '';
        }
        if($subjects){
            $subjectKeys = array_keys($subjects);
            sort($subjectKeys);
            foreach($subjectKeys as $oid){
                $fullname = $this->dbRead->One("SELECT getObjectFullName(".$oid.")");
                $keyword = $this->dbRead->One("SELECT getObjectKeyword(".$oid.")");
                $subjects[$oid] = $fullname;
                $subjectKeywords[$oid] = $keyword;
            }
        }
        if($objects){
            $objKeys = array_keys($objects);
            sort($objKeys);
            $objects = $this->dbRead->Table("SELECT o_id,o_name,o_keyword FROM `object` where o_id in(".implode(',',$objKeys).")");
            $objects = array_column($objects, null, 'o_id');
        }
		foreach($rows as $i=>$row){
            if(isset($subjects[$row['v_subject']])) $row['subjectText'] = $subjects[$row['v_subject']];
            if(isset($subjectKeywords[$row['v_subject']])) $row['subjectKeyword'] = $subjectKeywords[$row['v_subject']];
            if(isset($objects[$row['v_object_1']])) {
                $row['depText'] = $objects[$row['v_object_1']]['o_name'];
                //$row['depKeyword'] = $objects[$row['v_object_1']]['o_keyword'];
            }
            if(isset($objects[$row['v_object_2']])) {
                $row['staffText'] = $objects[$row['v_object_2']]['o_name'];
                //$row['staffKeyword'] = $objects[$row['v_object_2']]['o_keyword'];
            }
            if(isset($objects[$row['v_object_4']])) {
                $row['clientText'] = $objects[$row['v_object_4']]['o_name'];
                //$row['clientKeyword'] = $objects[$row['v_object_2']]['o_keyword'];
            }else{
				$row['clientText'] = $row['v_client'];
			}
            $rows[$i] = $row;
        }
	}
	/**
	 * Method 取当前凭证号状态
	 * @return int
	 */
	public function getState($cycle,$seq){
		return $this->getOne('v_state', sprintf("v_cycle=%s AND v_seq=%s", $cycle,$seq));
	}
	/**
	 * Method 已结算的最大周期
	 * @return int
	 */
	public function maxCheckoutCycle(){
		$row = $this->getRowSelectTable("voucher_checkout","ifnull(max(vc_cycle),0) max");
		return $row['max'];
	}
	/**
	 * Method 计算当前凭证周期是否已结算
	 * @return int
	 */
	public function isCheckout($cycle){
		return ($cycle <= $this->maxCheckoutCycle());
	}
	/**
	 * Method 计算当前凭证号是否已审核
	 * @return int
	 */
	public function isExamine($cycle, $seq)
	{
		$state = $this->getState($cycle, $seq);
		return ($state == 1) ? true : false;
	}

	/**
	 * 导入凭证记录列表
	 * @param string $where 查询sql条件
	 * @param int $page 页码(从1开始)
	 * @param int $pagesize 分页大小
	 * @param string $sidx 排序字段(单个)
	 * @param string $sord 排序方式 asc|desc
	 * @param string $orderby 排序sql(可多个)[优先]
	 * @return array 数据集
	 */
	public function listImport($where = '', $page = 0, $pagesize = 0, $sidx = '', $sord = 'asc', $orderby = '')
	{
		$e = require(mvc::$cfg['ROOT'] . 'mod/element/voucher_import.php');
		$sql = $e['view'];
		if (trim($where) != '') {
			if (strtolower(substr(trim($where), 0, 3)) !== 'and') $where = ' AND ' . $where;
			$sql .= $where;
		}
		if ($sidx == '' && $orderby == "") $orderby =  $e['order']; //默认排序
		if ($orderby != '') {
			$sql .= sprintf(' ORDER BY %s', $orderby);
		} else if ($sidx != '') {
			$sql .= sprintf(' ORDER BY %s %s', $sidx, $sord);
		}
		if ($page > 0 && $pagesize > 0) {
			$pages = $this->dbRead->PageLimit($sql, $page, $pagesize);
			$sql .= $pages['limit'];
		}
		$rows = $this->dbRead->Table($sql);
		$vim_id_arr = [];
		/*
		foreach($rows as $k=>$row){
			if($row['vim_is_create']=='1'){
				$vim_id_arr[$row['vim_id']] = true;
				$rows[$k]['vim_is_create'] = 0;
			}
		}
		if($vim_id_arr){
			$vim_id_string = implode(',', array_keys($vim_id_arr));
			$findRows = $this->dbRead->Table('SELECT v_from_id FROM voucher WHERE `v_from`="import" AND v_from_id in ('. $vim_id_string.')');
			$findIds = [];
			foreach($findRows as $frow){
				$findIds[$frow['v_from_id']] = true; 
			}
			foreach ($rows as $k => $row) {
				if (isset($findIds[$row['vim_id']])) {
					$rows[$k]['vim_is_create'] = 1;
				}
			}
		}*/
		//dd($rows);
		$footerData = [];
		$data = [
			'page' => $pages['page'],
			'total' => $pages['total'],
			'records' => $pages['records'],
			"userdata" => $footerData,
			'rows' => $rows
		];
		return $data;
	}

	/**
	 * 删除某月凭证记录列表
	 * @param string $where 查询sql条件
	 * @param int $page 页码(从1开始)
	 * @param int $pagesize 分页大小
	 * @param string $sidx 排序字段(单个)
	 * @param string $sord 排序方式 asc|desc
	 * @param string $orderby 排序sql(可多个)[优先]
	 * @return array 数据集
	 */
	public function deleteImport($type, $cycle)
	{
		$logic = new logicMod();
		$db = $logic->db;
		$date = substr($cycle, 0, 4).'-'. substr($cycle, 4, 2);
		$dateBegin = $date . '-01';
		$dateEnd = date('Y-m-t', strtotime($date)); 
		$q = (new sqler($db))->table('voucher_import');
		$q->where('vim_type', $type)->and('vim_date{>=}', $dateBegin)->and('vim_date{<=}', $dateEnd);
		$db->delete($q);
		return true;
	}

	/**
	 * 导入凭证记录，不直接生成凭证
	 */
	public function import(array $data)
	{
		if(!$data) return false;
		$logic = new logicMod();
		$db = $logic->db;
		$q = (new sqler($db))->table('object');
		$insertQ = (new sqler())->table('voucher_import');
		$insertData = [];
		$cacheObjectArr = [];
		foreach($data as $k=>$v){
			//借方科目
			$j_text = $v['j_text'];
			$oParent = 200;
			$oKey = $oParent . '.' . $j_text;
			if(!isset($cacheObjectArr[$oKey])){
				$cacheObjectArr[$oKey] = $q->clearWhere()->or(['o_code'=>$j_text,'o_name'=>$j_text])->one();
			}
			$j_id = $cacheObjectArr[$oKey];
			if(empty($j_id)){
				return '未找到借方科目: ' . $j_text;
			}

			//贷方科目
			$d_text = $v['d_text'];
			$oParent = 200;
			$oKey = $oParent.'.'. $d_text;
			if (!isset($cacheObjectArr[$oKey])) {
				$cacheObjectArr[$oKey] = $q->clearWhere()->or(['o_code' => $d_text, 'o_name' => $d_text])->one();
			}
			$d_id = $cacheObjectArr[$oKey];
			if (empty($j_id)) {
				return '未找到贷方科目: ' . $d_text;
			}

			//部门
			$object_1 = 0;
			$depa = isset($v['depa']) && $v['depa'] != '' ? $v['depa'] : '';
			if ($depa) {
				$oParent = 1;
				$oKey = $oParent . '.' . $depa;
				if (!isset($cacheObjectArr[$oKey])) {
					$cacheObjectArr[$oKey] = $q->clearWhere()->and('o_parent_id', $oParent)->or(['o_code' => $depa, 'o_name' => $depa])->one();
				}
				$object_1 = $cacheObjectArr[$oKey];
				if (empty($object_1)) {
					return '未找到部门: ' . $depa;
				}
			}

			//职员
			$object_2 = 0;
			$staff = isset($v['staff']) && $v['staff'] != '' ? $v['staff'] : '';
			if ($staff) {
				$oParent = 2;
				$oKey = $oParent . '.' . $staff;
				if (!isset($cacheObjectArr[$oKey])) {
					$cacheObjectArr[$oKey] = $q->clearWhere()->and('o_parent_id', $oParent)->or(['o_code' => $staff, 'o_name' => $staff])->one();
				}
				$object_2 = $cacheObjectArr[$oKey];
				if (empty($object_2)) {
					return '未找到职员: ' . $staff;
				}
			}
			$item = [
				'vim_group' => $v['group'],
				'vim_type' => $v['type'],
				'vim_j_id' => $j_id,
				'vim_j_text' => $j_text,
				'vim_d_id' => $d_id,
				'vim_d_text' => $d_text,
				'vim_money' => $v['money'],
				'vim_object_1' => $object_1,
				'vim_object_2' => $object_2,
				'vim_depa' => $depa,
				'vim_staff' => $staff,
				'vim_client' => $v['client'],
				'vim_summary' => $v['summary'],
				'vim_date' => $v['date'],
			];
			$insertData[] = $item;
		}
		$insertQ->push($insertData);
		$db->insert($insertQ);
		return true;
	}


	/**
	 * 生成导入凭证记录的凭证
	 * @param string $where 查询sql条件
	 * @param int $page 页码(从1开始)
	 * @param int $pagesize 分页大小
	 * @param string $sidx 排序字段(单个)
	 * @param string $sord 排序方式 asc|desc
	 * @param string $orderby 排序sql(可多个)[优先]
	 * @return array 数据集
	 */
	public function createVoucherFromImport($where = '', $page = 0, $pagesize = 0, $sidx = '', $sord = 'asc', $orderby = '')
	{
		//$e = require(mvc::$cfg['ROOT'] . 'mod/element/voucher_import.php');
		//$sql = $e['view'];
		//$where .= ' AND vim_is_create=0 ';
		$sql = "select voucher_import.* from voucher_import where not exists(select 1 from voucher where v_from='import' and v_from_id=vim_id)";
		if (trim($where) != '') {
			if (strtolower(substr(trim($where), 0, 3)) !== 'and') $where = ' AND ' . $where;
			$sql .= $where;
		}
		//if ($sidx == '' && $orderby == "") $orderby =  $e['order']; //默认排序
		if ($orderby != '') {
			$sql .= sprintf(' ORDER BY %s', $orderby);
		} else if ($sidx != '') {
			$sql .= sprintf(' ORDER BY %s %s', $sidx, $sord);
		}
		if ($page > 0 && $pagesize > 0) {
			$pages = $this->dbRead->PageLimit($sql, $page, $pagesize);
			$sql .= $pages['limit'];
		}
		$rows = $this->dbRead->Table($sql);

		//规档
		$data = [];
		foreach ($rows as $k => $row) {
			$data[$row['vim_date'].'.'.$row['vim_group']][] = $row;
		}
		
		$logic = new logicMod();
		$db = $logic->db;
		$insertData = [];
		$cycleSeqArr = [];
		$fromIdArr = [];
		foreach($data as $k=>$items){
			$firstItem = reset($items);
			$time = strtotime($firstItem['vim_date']);
			$cycle = date('Ym', $time);
			//获取当月下一个期号
			if (!isset($cycleSeqArr[$cycle])) {
				$seq = $logic->getMaxCycleByYearMonth($cycle) + 1;
			} else {
				$seq = $cycleSeqArr[$cycle] + 1;
			}
			$cycleSeqArr[$cycle] = $seq;

			//初始化
			foreach ($items as $k=>$v) {
				//取余额方向
				$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;
				}*/
				$v = [
					'money'    => $v['vim_money'],
					'j_id'    => $v['vim_j_id'],
					'd_id'    => $v['vim_d_id'],
					//'v_id'       =>'',
					'v_cycle'    => $cycle,
					'v_seq' => $seq,
					'v_year' => date('Y', $time),
					'v_date' => date('Y-m-d', $time),
					//'v_subject' => ,
					'v_j' => 0,
					'v_d' => 0,
					'v_direction' => $v_direction,
					'v_object_1' => $v['vim_object_1'],
					'v_object_2' => $v['vim_object_2'],
					'v_object_4' => 0,
					'v_client' => $v['vim_client'],
					'v_summary' => $v['vim_summary'],
					'v_state' => 0,
					'v_from' => 'import',
					'v_from_id' => $v['vim_id'],
					//'create_time' => '',
					//'update_time' => '',				
				];
				$items[$k] = $v;
				$fromIdArr[] = $v['v_from_id'];
			}
			//借方条目
			$jArr = [];
			foreach ($items as $k => $v) {
				if(!isset($jArr[$v['j_id']])) $jArr[$v['j_id']] = $v;
				$jArr[$v['j_id']]['v_j'] += $v['money'];
				$jArr[$v['j_id']]['v_subject']  = $v['j_id'];
				unset($jArr[$v['j_id']]['j_id']);
				unset($jArr[$v['j_id']]['d_id']);
				unset($jArr[$v['j_id']]['money']);
			}

			//贷方条目
			$dArr = [];
			$v_d = 0;
			foreach ($items as $k => $v) {
				if (!isset($dArr[$v['d_id']])) $dArr[$v['d_id']] = $v;
				$dArr[$v['d_id']]['v_d'] += $v['money'];
				$dArr[$v['d_id']]['v_subject']  = $v['d_id'];
				unset($dArr[$v['d_id']]['j_id']);
				unset($dArr[$v['d_id']]['d_id']);
				unset($dArr[$v['d_id']]['money']);
			}


			foreach ($jArr as $v) {
				$insertData[] = $v;
			}
			foreach ($dArr as $v) {
				$insertData[] = $v;
			}
		}
		$insertQ = (new sqler($db))->table('voucher');
		$updateQ = (new sqler($db))->table('voucher_import');
		$updateQ->where('vim_id', $fromIdArr)->set('vim_is_create',1);
		$insertQ->push($insertData);
		$db->begin();
			if(!empty($insertData)) $db->insert($insertQ);
			if(!empty($fromIdArr)) $db->update($updateQ);
		$db->end();
		return true;
	}

}

