package com.dhcc.finance.main.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.dhcc.common.constant.FinanceStatusCode;
import com.dhcc.common.constant.SysConstants;
import com.dhcc.common.constant.SysStatusCode;
import com.dhcc.common.model.CurrencyMeta;
import com.dhcc.common.model.SysUserInfo;
import com.dhcc.common.model.response.RestfulResponse;
import com.dhcc.common.util.CacheDataUtil;
import com.dhcc.common.util.SnowflakeIdWorker;
import com.dhcc.finance.constant.FinanceDictConsts;
import com.dhcc.finance.main.dao.CwBdAccassMapper;
import com.dhcc.finance.main.dao.CwBdAccsubjMapper;
import com.dhcc.finance.main.domain.CwBdAccass;
import com.dhcc.finance.main.domain.CwBdAccsubj;
import com.dhcc.finance.main.domain.CwBdAccsubjExample;
import com.dhcc.finance.main.domain.CwBdAccsubjExample.Criteria;
import com.dhcc.finance.main.model.CwBdAccsubjManage;
import com.dhcc.finance.main.service.CwBdAccsubjService;
import com.dhcc.finance.util.MetaDataUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import brave.Tracer;

/**
 * 功能描述：会计科目接口实现
 * @author dml
 * @date 2019年3月21日 下午9:27:28
 * @修改日志：
 */
@Service
public class CwBdAccsubjServiceImpl implements CwBdAccsubjService {
	
	@Autowired
	CwBdAccsubjMapper cwBdAccsubjMapper;
	
	@Autowired
	CwBdAccassMapper cwBdAccassMapper;
	
	@Autowired
	private Tracer tracer;
	
	@Autowired
	private StringRedisTemplate stringRedisTemplate;
	
	/*
	 * (非 Javadoc)  
	 * <p>Title: addCwBdSubjscheme</p>  
	 * <p>Description: 新增会计科目
	 * @param cwBdAccsubj
	 * @return  
	 * @see com.dhcc.finance.main.service.CwBdAccsubjService#addCwBdSubjscheme(com.dhcc.finance.main.domain.CwBdAccsubj)    
	 * @author dml
	 * @date 2019年3月21日 下午9:34:59
	 * @修改日志：
	 */
	@Transactional(rollbackFor = Exception.class)
	@Override
	public RestfulResponse<Object, CurrencyMeta> addCwBdAccsubj(CwBdAccsubjManage cwBdAccsubjManage) {
		SysUserInfo sysUserInfo = CacheDataUtil.<SysUserInfo>getCacheBean(stringRedisTemplate, SysConstants.REDIS_KEY_PREFIX.SYS_USER_INFO, SysUserInfo.class);
		if (sysUserInfo != null) {
			cwBdAccsubjManage.setCreateUser(sysUserInfo.getUserId());
		}
		cwBdAccsubjManage.setCreateTime(new Date());
		String rowKey = SnowflakeIdWorker.getInstance().nextIdString();
		cwBdAccsubjManage.setPkAccsubj(rowKey);
		cwBdAccsubjManage.setUseState(FinanceDictConsts.Syzt.EFFECTIVE);
		cwBdAccsubjManage.setDispname(cwBdAccsubjManage.getSubjname());
		// 新增科目
		CwBdAccsubj cwBdAccsubj = new CwBdAccsubj();
		BeanUtils.copyProperties(cwBdAccsubjManage, cwBdAccsubj);
	    cwBdAccsubjMapper.insert(cwBdAccsubj);
		//新增辅助项
	    List<CwBdAccass> listCwBdAccass = new ArrayList<>();
	    listCwBdAccass = cwBdAccsubjManage.getCwBdAccassList();
	    if (listCwBdAccass != null && listCwBdAccass.size()>0) {
		   listCwBdAccass.forEach(x ->{
		    	if (sysUserInfo != null) {
					x.setCreateUser(sysUserInfo.getUserId());
				}
		    	x.setCreateTime(new Date());
		    	x.setUseState(FinanceDictConsts.Syzt.EFFECTIVE);
		    	x.setIsmust(FinanceDictConsts.Syzt.EFFECTIVE);
		    	x.setPkAccass(SnowflakeIdWorker.getInstance().nextIdString());
		    	x.setPkSubjscheme(cwBdAccsubjManage.getPkSubjscheme());
		    	x.setPkAccsubj(cwBdAccsubjManage.getPkAccsubj());
		    });
			cwBdAccassMapper.insertCwBdAccassBatch(listCwBdAccass);
		
	   	}
		return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.SUCCESS,SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS,
				MetaDataUtil.getMeta(tracer,SysStatusCode.OPERATION_SUCCESS));
	}

	/*
	 * (非 Javadoc)  
	 * <p>Title: updateCwBdAccsubjByPk</p>  
	 * <p>Description: 通过主键修改会计科目
	 * @param cwBdSubjscheme
	 * @return  
	 * @see com.dhcc.finance.main.service.CwBdAccsubjService#updateCwBdAccsubjByPk(com.dhcc.finance.main.domain.CwBdAccsubj)    
	 * @author dml
	 * @date 2019年3月22日 上午9:04:50
	 * @修改日志：
	 */
	@Override
	public RestfulResponse<Object, CurrencyMeta> updateCwBdAccsubjByPk(CwBdAccsubj cwBdAccsubj) {
		SysUserInfo sysUserInfo = CacheDataUtil.<SysUserInfo>getCacheBean(stringRedisTemplate, SysConstants.REDIS_KEY_PREFIX.SYS_USER_INFO, SysUserInfo.class);
		if (sysUserInfo != null) {
			cwBdAccsubj.setUpdateUser(sysUserInfo.getUserId());
		}
		cwBdAccsubj.setUpdateTime(new Date());
		int res = cwBdAccsubjMapper.updateByPrimaryKeySelective(cwBdAccsubj);
		if (res > 0) {
			return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.SUCCESS,SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS,
					MetaDataUtil.getMeta(tracer,SysStatusCode.OPERATION_SUCCESS));
		}else {
			return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL,SysStatusCode.SERVER_UNKNOWN_ERROR.message(),
					MetaDataUtil.getMeta(tracer,SysStatusCode.OPERATION_SUCCESS));
		}
	}
	/*
	 * (非 Javadoc)  
	 * <p>Title: deleteCwBdAccsubjByPk</p>  
	 * <p>Description: 逻辑删除会计科目及相关信息
	 * @param cwBdAccsubj
	 * @return  
	 * @see com.dhcc.finance.main.service.CwBdAccsubjService#deleteCwBdAccsubjByPk(com.dhcc.finance.main.domain.CwBdAccsubj)    
	 * @author dml
	 * @date 2019年3月22日 上午9:09:30
	 * @修改日志：
	 */
	@Transactional(rollbackFor = Exception.class)
	@Override
	public RestfulResponse<Object, CurrencyMeta> deleteCwBdAccsubjByPk(String pkAccsubj,String pkSubjscheme) {
		SysUserInfo sysUserInfo = CacheDataUtil.<SysUserInfo>getCacheBean(stringRedisTemplate, SysConstants.REDIS_KEY_PREFIX.SYS_USER_INFO, SysUserInfo.class);
		Long count = cwBdAccsubjMapper.selectIsExistsSubForVoucher(pkAccsubj);
		if(count>0){
			return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL, FinanceStatusCode.VOUNCHER_HAS_SUB.message(),MetaDataUtil.getMeta(tracer, FinanceStatusCode.VOUNCHER_HAS_SUB));
		}
		List<CwBdAccsubj> selectByNode = cwBdAccsubjMapper.selectByNode(pkSubjscheme, pkAccsubj);
		List<String> nodeList = new ArrayList<>();
		selectByNode.forEach(x -> nodeList.add(x.getPkAccsubj()));
 		Map<String, Object> map = new HashMap<String, Object>();
 		map.put("list", nodeList);
 		map.put("updateTime", new Date());
 		if (sysUserInfo != null) {
 			map.put("updateUser", sysUserInfo.getUserId());
		}
 		cwBdAccsubjMapper.updateSubjschemeBatch(map);
 		cwBdAccassMapper.updateBypPkAccsubj(map);
		return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.SUCCESS,SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS,
				MetaDataUtil.getMeta(tracer,SysStatusCode.OPERATION_SUCCESS));
	}

	/*
	 * (非 Javadoc)  
	 * <p>Title: searchCwBdAccsubjByNode</p>  
	 * <p>Description: 查询节点和该节点下所有会计科目信息
	 * @param pageNum
	 * @param pageSize
	 * @param navigatePages
	 * @param pkSubjscheme 科目版本
	 * @param subjcode 科目节点
	 * @return  
	 * @see com.dhcc.finance.main.service.CwBdAccsubjService#searchCwBdAccsubjByNode(int, int, int)    
	 * @author dml
	 * @date 2019年3月22日 上午9:16:22
	 * @修改日志：
	 */
	@Override
	public RestfulResponse<PageInfo<CwBdAccsubj>, CurrencyMeta> searchCwBdAccsubjByNode(String pkSubjscheme, String subjcode, int pageNum, int pageSize,
			int navigatePages) {
		/*//PageHelper.startPage(pageNum, pageSize);
		List<CwBdAccsubj> selectByExample = cwBdAccsubjMapper.selectByNode(pkSubjscheme,subjcode);
		//PageInfo<CwBdAccsubj> pageInfo = new PageInfo<>(selectByExample, navigatePages);
		// 手动计算分页，暂时没找到调用存储过程时怎么用PageHelper分页
		List<CwBdAccsubj> listCwBdAccsubj = new ArrayList<>();
		if (selectByExample.size() >= pageNum * pageSize) {
			listCwBdAccsubj = selectByExample.subList((pageNum - 1) * pageSize, pageNum * pageSize);
		} else {
			if ((pageNum - 1) * pageSize <= selectByExample.size()) {
				listCwBdAccsubj = selectByExample.subList((pageNum - 1) * pageSize, selectByExample.size());
			} else {
				listCwBdAccsubj = selectByExample.subList(selectByExample.size() - selectByExample.size() % pageSize,
						selectByExample.size());
			}
		}
		//设置分页对象的部分值
		PageInfo<CwBdAccsubj> pageInfo = new PageInfo<CwBdAccsubj>();
		pageInfo.setList(listCwBdAccsubj);
		pageInfo.setPageSize(pageSize);
		pageInfo.setPageNum(pageNum);
		pageInfo.setNavigatePages(navigatePages);
		pageInfo.setTotal(selectByExample.size());
		*/
		PageHelper.startPage(pageNum, pageSize);
		List<CwBdAccsubj> selectByExample = cwBdAccsubjMapper.selectByNode(pkSubjscheme,subjcode);
		PageInfo<CwBdAccsubj> pageInfo = new PageInfo<>(selectByExample, navigatePages);
		return new RestfulResponse<PageInfo<CwBdAccsubj>, CurrencyMeta>(SysConstants.CODE.SUCCESS,SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS,
				pageInfo,MetaDataUtil.getMeta(tracer,SysStatusCode.OPERATION_SUCCESS));
	}
	
	/*
	 * (非 Javadoc)  
	 * <p>Title: searchCwBdAccsubjAllData</p>  
	 * <p>Description:查询全部会计科目
	 * @param pkSubjscheme
	 * @param pageNum
	 * @param pageSize
	 * @param navigatePages
	 * @return  
	 * @see com.dhcc.finance.main.service.CwBdAccsubjService#searchCwBdAccsubjAllData(java.lang.String, int, int, int)    
	 * @author dml
	 * @date 2019年3月22日 上午9:37:41
	 * @修改日志：
	 */
	@Override
	public RestfulResponse<List<CwBdAccsubj>, CurrencyMeta> searchCwBdAccsubjAllData(String pkSubjscheme) {
		CwBdAccsubjExample cwBdAccsubjExample = new CwBdAccsubjExample();
		Criteria create = cwBdAccsubjExample.createCriteria();
		create.andUseStateEqualTo(FinanceDictConsts.Syzt.EFFECTIVE);
		create.andPkSubjschemeEqualTo(pkSubjscheme);
		List<CwBdAccsubj> selectByExample = cwBdAccsubjMapper.selectByExample(cwBdAccsubjExample);
		return new RestfulResponse<List<CwBdAccsubj>, CurrencyMeta>(SysConstants.CODE.SUCCESS,SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS,
				selectByExample,MetaDataUtil.getMeta(tracer,SysStatusCode.OPERATION_SUCCESS));
	}

	/* (非 Javadoc)  
	 * <p>Title: searchCwBdAccsubjByName</p>  
	 * <p>Description: </p>
	 * @param pkSubjscheme
	 * @param subjname
	 * @param pageNum
	 * @param pageSize
	 * @param navigatePages
	 * @return  
	 * @see com.dhcc.finance.main.service.CwBdAccsubjService#searchCwBdAccsubjByName(java.lang.String, java.lang.String, int, int, int)    
	 * @author huangpeng
	 * @date 2019年3月29日 下午3:07:54
	 * @修改日志：
	 */
	
	@Override
	public RestfulResponse<PageInfo<CwBdAccsubj>, CurrencyMeta> searchCwBdAccsubjByName(String pkSubjscheme,
			String subjname, int pageNum, int pageSize, int navigatePages) {
		PageHelper.startPage(pageNum, pageSize);
		CwBdAccsubjExample cwBdAccsubjExample = new CwBdAccsubjExample();
		Criteria create = cwBdAccsubjExample.createCriteria();
		create.andUseStateEqualTo("1");
		create.andSubjnameEqualTo(subjname);
		create.andPkSubjschemeEqualTo(pkSubjscheme);
		List<CwBdAccsubj> selectByExample = cwBdAccsubjMapper.selectByExample(cwBdAccsubjExample);
		PageInfo<CwBdAccsubj> pageInfo = new PageInfo<>(selectByExample, navigatePages);
		return new RestfulResponse<PageInfo<CwBdAccsubj>, CurrencyMeta>(SysConstants.CODE.SUCCESS,SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS,
				pageInfo,MetaDataUtil.getMeta(tracer,SysStatusCode.OPERATION_SUCCESS));
	}

	/*
	 * (非 Javadoc)  
	 * Title: selectNowUseCwBdAccsubj 
	 * Description:查询现在正启用的版本下的所有科目
	 * @return  
	 * @see com.dhcc.finance.main.service.CwBdAccsubjService#selectNowUseCwBdAccsubj()    
	 * @author dml
	 * @date 2019年4月2日 下午4:04:17
	 * @修改日志：
	 */
	@Override
	public RestfulResponse<List<CwBdAccsubj>, CurrencyMeta> selectNowUseCwBdAccsubj() {
		List<CwBdAccsubj> selectNowUseCwBdAccsubj = cwBdAccsubjMapper.selectNowUseCwBdAccsubj();
		return new RestfulResponse<List<CwBdAccsubj>, CurrencyMeta>(SysConstants.CODE.SUCCESS,SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS,
				selectNowUseCwBdAccsubj,MetaDataUtil.getMeta(tracer,SysStatusCode.OPERATION_SUCCESS));
	}

	/* (非 Javadoc)  
	 * <p>Title: selectCwBdAccsubjByPk</p>  
	 * <p>Description: </p>
	 * @param pkAccsubj
	 * @return  
	 * @see com.dhcc.finance.main.service.CwBdAccsubjService#selectCwBdAccsubjByPk(java.lang.String)    
	 * @author huangpeng
	 * @date 2019年4月28日 下午5:27:03
	 * @修改日志：
	 */
	
	@Override
	public RestfulResponse<CwBdAccsubj, CurrencyMeta> selectCwBdAccsubjByPk(String pkAccsubj) {
		CwBdAccsubj cwBdAccsubj = cwBdAccsubjMapper.selectByPrimaryKey(pkAccsubj);
		return  new RestfulResponse<CwBdAccsubj, CurrencyMeta>(SysConstants.CODE.SUCCESS,SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS,
				cwBdAccsubj,MetaDataUtil.getMeta(tracer,SysStatusCode.OPERATION_SUCCESS));
	}

}
