<?php
/*
 [
    'key'=>'rule1',                             //键名
    'caption'=>'编码规则',                      //字段名
    'must'=> true,                              //是否必须,默认false
    'mustCols'=> ['ruleA','ruleB']              //当此列存在时，必须有的其他列 ，默认空
    'minlen'=>0,                                //最小长度 默认0不判断
    'maxlen'=>50,                               //最大长度 默认0不判断
    'type'=>'number',                           //类型 number,string 默认 string
    //自定义检测
    'checkfunction'=>function($arr, $k, $v, $obj){
        $obj->lastError = '[line:'.$obj->lineNum.'] ['.$obj->rules[$k]['caption'].'] 自定义检测, 当前值为[ '.$v.' ]';
        return false;
    }
     //格式化单元格的值 [
        类, 
        类的创建参数, 默认[]
        方法, 
        参数,  ['@innum','@outnum',123,true] @表示使用导入数据中的列中的值 ,'@'表示自己 
        如果结果是数组指定返回哪个键 默认null
     ]
    'formatCell'=> [\model\collocation::class,'getRowByKey',['@'],null],   或者 config/import.php 中的配置
],
 */
 
namespace model\import;
use \model;
use \model\check;
use \model\work;
use \model\collocation;
use \model\carmodel;
use \model\pro\factory;

/**
 * 
 */
class workdata  extends model
{
	public $title = '数据工单'; //固定
	public $import = null;    //固定
	public $rules = null;    //规则
	public $demoData = null;  //样例数据
	public $demoremark = null;  //样例说明
	public $rulesUpdate = null;    //更新规则
	public $importdata = []; //固定
	public $head = []; //固定
	public $params = null; 
	
	public function __construct()
	{
		parent::__construct();
	}
	
	 /**处理导入
     * @param array|string $src 数组或者文件名
     * @param isInit 是否是初始化
     * @return 可返回任意值(string|array|bool)，都会到前端
     */
    public function import($src,$isInit=false) //固定
    {
		$this->src = $src;
		$state = true;
		$wdlInfo = [];
		$excel = new \model\excel();
		$this->importdata = $excel->readOnly($src, 0);
		//$this->importdata = $excel->readAnyType($src);
		$this->head = $this->importdata[0];
		$factory = new factory();
		//需要提取的列
		$colArr = [];//列对应的信息
		$hasType = [];//类型对应的列
		foreach($this->importdata[0] as $k=>$v){
			if(in_array($v, \mvc::$cfg['workDataType']) && !empty($this->importdata[1][$k])){
				$hasType[$v][] = $k;
				$colArr[$k] = ['name'=>$this->importdata[1][$k], 'type'=>$v, 'colnum'=>$k];
			}
		}
		

		if($this->params['wdlist_id']){
			//表头是否一致
			$wdlArr = $this->db->get('work_data_list', ['wdlist_id', 'wdlist_seq', 'wdlist_cols'], ['wdlist_id'=>$this->params['wdlist_id']]);
			$wdlist_seq = $wdlArr['wdlist_seq'];
			$wdlist_id = $this->params['wdlist_id'];
			/*$oldArr = json_decode($wdlArr['wdlist_cols'], true);
			if(array_column($colArr, 'name') != array_column($oldArr, 'name') || array_column($colArr, 'type') != array_column($oldArr, 'type')){
				$this->importdata[1]['excelInfo']['error'][] = '表头格式和第一次导入表头格式不一致';
				$state = false;
				return $this->output([]);
			}*/
		}
		
		$cache = [];
		$cate = new \model\pro\cate();
		$carmodel = new \model\carmodel();
		$formatType = ['Supplier', 'Cate', 'Make'];
		foreach($this->importdata as $line=>&$dv){
			$dv['excelInfo'] = [
				'line'=>$line,
				'error'=>[]
			];
			if($line < 2){
				if($line == 1){
					/*if(empty($hasType['Supplier'])){
						$dv['excelInfo']['error'][] = '[Supplier]供应商编码列缺失';
						$state = false;
					}*/
					if(empty($hasType['OE']) && empty($hasType['FacNumber']) && empty($hasType['Number'])){
						$dv['excelInfo']['error'][] = '第一行至少有一列号码[OE、FacNumber、Number]';
						$state = false;
					}
				}
				if(!$state) break;
				continue;
			}
			foreach($hasType as $type=>$cols){
				//需要转格式化值的类型
				foreach($cols as $col){
					$val = $dv[$col];
					if(empty($val) || !in_array($type, $formatType)) continue;
					//优先取缓存
					if(isset($cache[$type][$val])){
						$valf = $cache[$type][$val];
					}else{
						if($type == 'Supplier'){
							$valf = $this->db->get('supplier', 'sup_id', ['sup_code'=>$val]);
						}else if($type == 'Cate'){
							$t = explode('.', $val);
							$valf = $cate->eqname($t[0], $t[1], 1);
						}else if($type == 'Make'){
							$tvals = strtr($val, ['，'=>',',';'=>',','；'=>',',"\n"=>',']);
							$valf = $carmodel->getOeMakeIds($tvals);
						}
						$cache[$type][$val] = $valf;
					}
					if(empty($valf)){
						$dv['excelInfo']['error'][] = '['.$type.']['.$val.']不存在';
						$state = false;
					}else if(empty($dv['excelInfo'][$type]) || !in_array($valf, $dv['excelInfo'][$type])){
						$dv['excelInfo'][$type][] = $valf;
					}
				}
			}
		}
		
		//入库
		if($state && !empty($this->importdata[2])){
			$work = new work();
			$opuser = getOpuser();
			$datetime = getNowTime();

			$this->db->Begin();
			$check = new check();
			//表头是厂商名
			foreach($colArr as $ck=>$cv){
				if($cv['type'] == 'FacNumber')
					$colArr[$ck]['pf_id'] = $factory->getFacId($cv['name'], 'add');
			}
			$noCatids = [];
			if(empty($wdlist_id)){
				$exists = $check->checkExist('wdlist_title', ['wdlist_title'=>$this->params['wdlist_title']]);
				if($exists) exitJson('标题已存在');
				$sup_id = $this->importdata[2]['excelInfo']['Supplier'][0]; 
				$wdl = [
					'wdlist_sup_id'=>$sup_id? $sup_id: 0,	
					'wdlist_seq'=>$work->getWorkSeqNext(),
					'wdlist_from_opuser'=>$this->params['wdlist_from_opuser']? $this->params['wdlist_from_opuser'] : '',
					//'wdlist_from_date'=>$this->params['wdlist_from_date']? $this->params['wdlist_from_date'] : '',
					'wdlist_title'=>$this->params['wdlist_title'],
					'wdlist_remark'=>$this->params['wdlist_remark']? $this->params['wdlist_remark'] : '',
					'wdlist_type'=>$this->params['wdlist_type'] ? $this->params['wdlist_type'] : 0,
					'wdlist_cols'=>json_encode($colArr, JSON_UNESCAPED_UNICODE),
					'wdlist_opuser'=>$opuser,
					'wdlist_create_time'=>$datetime,
					'wdlist_update_time'=>$datetime
				];
				$wdlist_seq = $wdl['wdlist_seq'];
				$this->db->insert('work_data_list', $wdl);
				$wdlist_id = $this->db->id();
			}

			foreach($this->importdata as $line=>&$dv){
				if($line < 2) continue;
				//剔除无效列数据
				$orgData = [];
				$toFormat = [];
				
				//汽车商格式化并合并
				if(!empty($dv['excelInfo']['Make'])){
					$tids = array_unique(explode(',', implode(',', $dv['excelInfo']['Make'])));
					foreach($tids as $tid){
						if(empty($tid)) continue;
						$toFormat['Make'][] = [
							'wdif_type'=>'Make',
							'wdif_val'=>$tid,
							'wdif_search'=>$tid,
						];
					}
				}
				$cat_id = (int) $dv['excelInfo']['Cate']? $dv['excelInfo']['Cate'][0]: 0; 
				$isborrow = 0;
				foreach($colArr as $ck=>$cv){
					if(stripos($cv['type'], 'Image') === 0){//图片
						$imgInfo = $dv[$ck];
						if(isset($imgInfo['path']) && $imgInfo['path'] && $imgInfo['ext']){
							$imagname = substr(md5($imgInfo['path']), 8, 16).'.'.$imgInfo['ext'];
							$imgPath = 'work/'.date('Ym');
							$imagefile = \mvc::$cfg['dir']['files'].'/'.$imgPath.'/'.$imagname;
							mkdirs(\mvc::$cfg['dir']['files'].'/'.$imgPath);
							if(!file_exists($imagefile)){
								switch ($imgInfo['ext']) {
									case 'jpg':
									case 'jpeg':
										$source = imagecreatefromjpeg($imgInfo['path']);
										imagejpeg($source, $imagefile);
										break;
									case 'gif':
										$source = imagecreatefromgif($imgInfo['path']);
										imagegif($source, $imagefile);
										break;
									case 'png':
										$source = imagecreatefrompng($imgInfo['path']);
										imagepng($source, $imagefile);
										break;
								}
							}
							$orgData[$ck] = $imgPath.'/'.$imagname;
						}else{
							$orgData[$ck] = '';
						}
					}else{
						$orgData[$ck] = $dv[$ck];
					}
					//号码
					if(in_array($cv['type'], ['OE','FacNumber','Number'])){
						$strNums = $orgData[$ck];
						$tnums = strtr($strNums, ['，'=>',',';'=>',','；'=>',',"\n"=>',', '：'=>':']);
						foreach(explode(',', $tnums) as $tnum){
							$isborrow = 0;
							if(stripos($tnum, '借用') !== false){
								$isborrow = 1;
								$tnum = trim(str_replace('借用', '', $tnum));
							}
							if(empty($tnum)) continue;
							$pfid = 0;
							if($cv['type'] == 'OE'){
								$pfid = 1;
							}else if($cv['type'] == 'FacNumber'){
								$pfid = $cv['pf_id'];
							}else{
								$tvs = explode(':', $tnum);
								if(count($tvs) >= 2){
									$pfid = $tvs[0] == 'OE'? 1: $factory->getFacId($tvs[0], 'add');
									$tnum = $tvs[1];
								}else{
									$pfid = 1;
									$tnum = $tvs[0];
								}
							}
							$tnumArr = [
								'wdif_type'=>'Number',
								'wdif_val'=>$tnum,
								'wdif_search'=>formatNum($tnum),
								'wdif_pf_id'=>$pfid? $pfid: 1,
								'wdif_isborrow'=>$isborrow
							];
							if($isborrow){
								$toFormat['Number'][] = $tnumArr;
							}else{
								$uniwhere = [
									'wdi_cat_id'=>$cat_id,
									'wdi_wdlist_id'=>$wdlist_id,
									'wdif_type'=>'Number',
									'wdif_search'=>$tnumArr['wdif_search'],
									'wdif_pf_id'=>$tnumArr['wdif_pf_id'],
									'wdif_isborrow'=>0
								];
								$chk = $this->db->get('work_data_item_format(wdif)', ["[><]work_data_item(wdi)"=>["wdif.wdif_wdi_id" =>"wdi_id"]], ['wdif_id'], $uniwhere);
								if(empty($chk)){
									$toFormat['Number'][] = $tnumArr;
								}else{
									$dv['excelInfo']['error'][] = $tnumArr['wdif_val'].'已存在';
									$state = false;
								}
							}
						}
					}else if(in_array($cv['type'], ['Engine','Model','P','Para','Image','Image2','Other']) && !empty($orgData[$ck])){
						$toFormat[$cv['type']][] = [
							'wdif_type'=>$cv['type'],
							'wdif_val'=>$orgData[$ck]
						];
					}else if(in_array($cv['type'], ['Borrow']) && !empty($orgData[$ck])){
						if(strtoupper(trim($orgData[$ck])) == 'Y' || $orgData[$ck] == '是') $isborrow = 1;
					}
				}
				if(!empty($toFormat['Number'])){
					$wdli = [
						'wdi_wdlist_id'=>$wdlist_id,
						'wdi_cat_id'=>$cat_id,
						'wdi_data'=>json_encode($orgData, JSON_UNESCAPED_UNICODE),
						'wdi_opuser'=>$opuser,
						'wdi_create_time'=>$datetime,
						'wdi_update_time'=>$datetime
					];
					$this->db->insert('work_data_item', $wdli);
					$wdi_id = $this->db->id();
					if(!$cat_id) $noCatids[] = $wdi_id;
					//格式化数据
					foreach($toFormat as $type=>$vals){
						//数组本身去重
						$vals = array_map('unserialize', array_unique(array_map('serialize', $vals)));
						foreach($vals as $vk=>$wdif){
							$vals[$vk]['wdif_wdi_id'] = $wdi_id;
						}
						$this->db->insert('work_data_item_format', $vals);
					}
				}
				
			}
			if($noCatids) $work->autoCleanCat(['ids'=>$noCatids]);
			if($state){
				$this->db->End();
				$wdlInfo =  ['wdlist_id'=>$wdlist_id, 'wdlist_seq'=>$wdlist_seq];
			}
		}
        return $this->output($wdlInfo); //生成处理结果
	}
	
	//通过输入号码导入
    public function importByTxt()
    {
		$wdlInfo = [];
		$factory = new factory();
		$nums = [];
		$tnums = strtr($this->params['nums'], ['，'=>',',';'=>',','；'=>',',"\n"=>',', '：'=>':']);
		foreach(explode(',', $tnums) as $tnum){
			if(empty($tnum)) continue;
			$tvs = explode(':', $tnum);
			if(count($tvs) >= 2){
				$pfid = $tvs[0] == 'OE'? 1: $factory->getFacId($tvs[0], 'add');
				$tnum = $tvs[1];
			}else{
				$pfid = 1;
				$tnum = $tvs[0];
			}
			$isborrow = 0;
			if(stripos($tnum, '借用') !== false){
				$isborrow = 1;
				$tnum = trim(str_replace('借用', '', $tnum));
			}
			$format = formatNum($tnum);
			$nums[$pfid.$format] = [
				'wdif_type'=>'Number',
				'wdif_val'=>$tnum,
				'wdif_search'=>$format,
				'wdif_pf_id'=>$pfid? $pfid: 1,
				'wdif_isborrow'=>$isborrow
			];
		}
		$nums = array_values($nums);
		if(empty($nums)) exitJson('号码必填');
		if($this->params['wdlist_id']){
			$wdlArr = $this->db->get('work_data_list', ['wdlist_id', 'wdlist_seq'], ['wdlist_id'=>$this->params['wdlist_id']]);
			$wdlist_seq = $wdlArr['wdlist_seq'];
			$wdlist_id = $this->params['wdlist_id'];
		}

		$work = new work();
		$opuser = getOpuser();
		$datetime = getNowTime();

		$this->db->Begin();
		$check = new check();
		
		if(empty($wdlist_id)){
			$exists = $check->checkExist('wdlist_title', ['wdlist_title'=>$this->params['wdlist_title']]);
			if($exists) exitJson('标题已存在');
			$wdl = [
				'wdlist_seq'=>$work->getWorkSeqNext(),
				'wdlist_from_opuser'=>$this->params['wdlist_from_opuser']? $this->params['wdlist_from_opuser'] : '',
				'wdlist_title'=>$this->params['wdlist_title'],
				'wdlist_remark'=>$this->params['wdlist_remark']? $this->params['wdlist_remark'] : '',
				'wdlist_opuser'=>$opuser,
				'wdlist_create_time'=>$datetime,
				'wdlist_update_time'=>$datetime
			];
			$wdlist_seq = $wdl['wdlist_seq'];
			$this->db->insert('work_data_list', $wdl);
			$wdlist_id = $this->db->id();
		}
		$noCatids = [];
		foreach($nums as $dv){
			if(!$isborrow){
				$uniwhere = [
					'wdi_wdlist_id'=>$wdlist_id,
					'wdif_type'=>'Number',
					'wdif_search'=>$dv['wdif_search'],
					'wdif_pf_id'=>$dv['wdif_pf_id'],
					'wdif_isborrow'=>0
				];
				$chk = $this->db->get('work_data_item_format(wdif)', ["[><]work_data_item(wdi)"=>["wdif.wdif_wdi_id" =>"wdi_id"]], ['wdif_id'], $uniwhere);
				if(!empty($chk)) continue;
			}
			
			$toFormat = ['Number'=>[$dv]];
			$wdli = [
				'wdi_wdlist_id'=>$wdlist_id,	
				'wdi_opuser'=>$opuser,
				'wdi_create_time'=>$datetime,
				'wdi_update_time'=>$datetime
			];
			$this->db->insert('work_data_item', $wdli);
			$wdi_id = $this->db->id();
			$noCatids[] = $wdi_id;
			//格式化数据
			foreach($toFormat as $type=>$vals){
				//数组本身去重
				$vals = array_map('unserialize', array_unique(array_map('serialize', $vals)));
				foreach($vals as $vk=>$wdif){
					$vals[$vk]['wdif_wdi_id'] = $wdi_id;
				}
				$this->db->insert('work_data_item_format', $vals);
			}
		}
		if($noCatids) $work->autoCleanCat(['ids'=>$noCatids]);
		$this->db->End();
		$wdlInfo = ['wdlist_id'=>$wdlist_id, 'wdlist_seq'=>$wdlist_seq];
        return $wdlInfo;
	}

	 /**
     * 写入内容
     * @return string filename
     */
	public function output($wdlInfo)
	{
		if(empty($wdlInfo['wdlist_id'])){
			$this->outfilename = $this->src . '.back.csv';
			//@unlink($this->src);
			$fp = fopen($this->outfilename, 'w');
			$head = $this->head;
			$head[] = '错误信息';
			$lastcol = count($head) - 1;
			fputcsv($fp, $head, ',','"');
			foreach($this->importdata as $line=>$row){
				if($line == 0) continue;
				$outRow = [];
				foreach($head as $col=>$hv){
					if($lastcol == $col){
						$val = $row['excelInfo']['error']? implode("\n", array_unique($row['excelInfo']['error'])): '';
					}else{
						$val = is_array($row[$col])? '': $row[$col];
					}
					$outRow[] = $val;
				}
				fputcsv($fp, $outRow, ',','"');
			}
			fclose($fp);
			return $this->outfilename;
		}else{
			return $wdlInfo;
		}
	}
}