/***文档注释***********************************************
 * 作者            ：
 * 创建日期     ：2019-06-11
 * 描述            ：成本核算顺序表
 * 注意事项     ：
 * 遗留BUG   ：
 * 修改日期     ：
 * 修改人员     ：
 * 修改内容     ：
***********************************************************/
package market.Cm.impl;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import market.Cm.mapper.BaseCptHistoryMapper;
import market.Cm.mapper.BaseCptIndexMapper;
import market.Cm.mapper.BaseDstItemMapper;
import market.Cm.mapper.BaseFiscalPeriodDMapper;
import market.Cm.mapper.CmReportCostMiddleMapper;
import market.Cm.mapper.CmReportProdCostMapper;
import market.Cm.mapper.CmReportProdDetailMapper;
import market.Cm.mapper.CmReportProdIosMapper;
import market.Cm.mapper.CmReportProdMatMapper;
import market.Cm.mapper.CmReportProdMiddleMapper;
import market.Cm.mapper.CmReportProdProcessMapper;
import market.Cm.mapper.CmReportProdTotalMapper;
import market.Cm.mapper.CostAcmProdMapper;
import market.Cm.service.BaseCptIndexService;
import market.Cm.vo.BaseCptHistory;
import market.Cm.vo.BaseCptIndex;
import market.Cm.vo.BaseDstItem;
import market.Cm.vo.BaseFiscalPeriodD;
import market.Cm.vo.BaseOracleTableInfo;
import market.Cm.vo.CmReportCostMiddle;
import market.Cm.vo.CmReportProdCost;
import market.Cm.vo.CmReportProdDetail;
import market.Cm.vo.CmReportProdIos;
import market.Cm.vo.CmReportProdMat;
import market.Cm.vo.CmReportProdMiddle;
import market.Cm.vo.CmReportProdProcess;
import market.Cm.vo.CmReportProdTotal;
import market.Com.vo.CommonPage;
import market.Com.vo.ResultModel;

import org.springframework.transaction.annotation.Transactional;

import com.hnshituo.basic.service.impl.BaseServiceImpl;
import com.hnshituo.basic.spring.remoting.annotation.RemoteService;
import com.hnshituo.core.auth.service.HomeService;

@RemoteService(path="BaseCptIndexService")
public class BaseCptIndexServiceImpl extends BaseServiceImpl<BaseCptIndex,Object> implements BaseCptIndexService {
	
	/**
	 * 查询成本核算顺序
	 * @param cp object[cpt_item_name计算项名称,dst_item_name分配项目名称,valid_flg是否有效]
	 * @return
	 * @throws Exception
	 */
	public ResultModel doQueryBaseCptIndex(CommonPage<BaseCptIndex> cp) throws Exception{
		ResultModel rm  = new ResultModel();
		BaseCptIndex bci = cp.getObject();
		try {
			String swhere = "";
			if (bci.getCpt_item_name()!=null && !"".equals(bci.getCpt_item_name())) {
				swhere+=" and t.cpt_item_name like  '%"+bci.getCpt_item_name()+"%'";//计算项名称
			}
			if (bci.getDst_item_name()!=null && !"".equals(bci.getDst_item_name())) {
				swhere+=" and bdi.dst_item_name like  '%"+bci.getDst_item_name()+"%'";//分配项目名称
			}			
			if (bci.getValid_flg()!=null && !"".equals(bci.getValid_flg())) {
				swhere+=" and t.valid_flg = '"+bci.getValid_flg()+"'"; //是否有效
			}
			List<BaseCptIndex> lists = this.getMapper(BaseCptIndexMapper.class).doQueryBaseCptIndex(swhere);
			rm.setData(lists);
			rm.setState("200");
			rm.setMsgInfo("查询成功");
		} catch (Exception e) {
			throw new Exception("查询失败，请联系管理员");
		}
		return rm;
	}
	
	/**
	 * 新增成本核算顺序
	 * @param cpi
	 * @return
	 * @throws Exception
	 */
	public ResultModel doInsertBaseCptIndex(CommonPage<BaseCptIndex> cp) throws Exception{
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		ResultModel rm = new ResultModel();
		BaseCptIndex bci = cp.getObject();
		//必填项验证 
		this.doCheckBaseCptIndex(bci);
		//相同核算项目名称验证
		BaseCptIndex BCI = new BaseCptIndex();
		BCI.setCpt_item_name(bci.getCpt_item_name());
		int count = this.getMapper(BaseCptIndexMapper.class).count(BCI);
		if (count > 0) {
			throw new Exception("核算项目名称【"+bci.getCpt_item_name()+"】已经存在");
		}
		//是否分配项目的验证
		if ("1".equals(bci.getIs_dst_item()) && bci.getDst_item_code()==null) {
			throw new Exception("【是否分配项目】已经勾选，请选择分配项目");
		}
		
		//生成计算项代码 CM001
		List<BaseCptIndex> list = this.getMapper(BaseCptIndexMapper.class).findWithCondition(null, null, "cpt_item_code desc", 0, 0);
		if (list==null || list.size()<=0) {
			bci.setCpt_item_code("CM001");
		}else {
			String maxCode = list.get(0).getCpt_item_code();
			String seq = maxCode.substring(maxCode.length()-3);
			int iseq = Integer.parseInt(seq) + 1;
			bci.setCpt_item_code("CM" + String.format("%03d", iseq));
		}
		bci.setCreate_man(userName);
		bci.setCreate_time(new Date());
		this.getMapper(BaseCptIndexMapper.class).insert(bci);
		rm.setState("200");
		rm.setMsgInfo("新增成功");
		return rm;
	}
	
	/**
	 * 修改成本核算顺序
	 * @param cp
	 * @return
	 * @throws Exception
	 */
	public ResultModel doUpdateBaseCptIndex(CommonPage<BaseCptIndex> cp) throws Exception{
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		ResultModel rm = new ResultModel();
		BaseCptIndex bci = cp.getObject();
		//必填项验证 
		this.doCheckBaseCptIndex(bci);
		if (bci.getCpt_item_code()==null || "".equals(bci.getCpt_item_code())) {
			throw new Exception("计算项目代码不能为空");
		}
		BaseCptIndex BCI = this.getMapper(BaseCptIndexMapper.class).findById(bci.getCpt_item_code());
		if (BCI==null) {
			throw new Exception("当前选择行的成本核算顺序信息不存在，请重新查询");
		}
		if ("0".equals(BCI.getValid_flg())) {
			throw new Exception("成本核算顺序信息【"+BCI.getCpt_item_name()+"】已经禁用，无法修改");
		}
		
		//判断名称是否重复
		String condition = "cpt_item_code <> '"+bci.getCpt_item_code()+"' and cpt_item_name = '"+bci.getCpt_item_name()+"' ";
		List<BaseCptIndex> list = this.getMapper(BaseCptIndexMapper.class).findWithCondition(null, condition, null, 0, 0);
		if (list!=null && list.size()>0) {
			throw new Exception("存在相同的计算项名称，无法修改");
		}
		//是否分配项目的验证
		if ("1".equals(bci.getIs_dst_item()) && bci.getDst_item_code()==null) {
			throw new Exception("【是否分配项目】已经勾选，请选择分配项目");
		}
		bci.setUpdate_man(userName);
		bci.setUpdate_time(new Date());
		this.getMapper(BaseCptIndexMapper.class).update(bci);		
		rm.setState("200");
		rm.setMsgInfo("修改成功");
		return rm;
	}
	
	/**
	 * 删除成本核算顺序
	 * @param cp cpt_item_code计算项代码
	 * @return
	 * @throws Exception
	 */
	public ResultModel doDeleteBaseCptIndex(CommonPage<BaseCptIndex> cp) throws Exception{
		ResultModel rm = new ResultModel();
		BaseCptIndex bci = cp.getObject();
		if (bci.getCpt_item_code()==null || "".equals(bci.getCpt_item_code())) {
			throw new Exception("请传入计算项代码");
		}
		this.getMapper(BaseCptIndexMapper.class).delete(bci.getCpt_item_code());
		rm.setState("200");
		rm.setMsgInfo("删除成功");
		return rm;
	}
	
	/**
	 * 启用/禁用成本核算顺序 memo1[0禁用 1启用]
	 * @param cp
	 * @return
	 * @throws Exception
	 */
	public ResultModel doChangeBaseCptIndexValidFlg(CommonPage<BaseCptIndex> cp) throws Exception{
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		ResultModel rm = new ResultModel();
		String opr = cp.getMemo1();
		String reslut = null;
		BaseCptIndex bci = cp.getObject();
		if (bci.getCpt_item_code()==null || "".equals(bci.getCpt_item_code())) {
			throw new Exception("请传入计算项代码");
		}
		bci.setUpdate_man(userName);
		bci.setUpdate_time(new Date());
		if ("1".equals(opr)) {//启用
			bci.setValid_flg("1");
			reslut = "启用";
		}else if ("0".equals(opr)) { //禁用
			bci.setValid_flg("0");
			reslut = "禁用";
		}
		this.getMapper(BaseCptIndexMapper.class).update(bci);
		rm.setState("200");
		rm.setMsgInfo(reslut + "操作成功");
		return rm;
	}
	
	/**
	 * 有效性验证
	 * @param bci
	 * @throws Exception
	 */
	public void doCheckBaseCptIndex(BaseCptIndex bci) throws Exception{
		if (bci.getCpt_item_name()==null || "".equals(bci.getCpt_item_name())) {
			throw new Exception("计算项目名称不能为空");
		}
		if (bci.getData_origin()==null || "".equals(bci.getData_origin())) {
			throw new Exception("数据来源不能为空");
		}
		if (bci.getData_opt()==null || "".equals(bci.getData_opt())) {
			throw new Exception("操作模式不能为空");
		}
		if (bci.getCpt_index()==null || "".equals(bci.getCpt_index())) {
			throw new Exception("计算顺序不能为空");
		}
		if (bci.getStart_date()==null || "".equals(bci.getStart_date())) {
			throw new Exception("操作日期不能为空");
		}
	}
	
	/**
	 * 查询数据库的表名
	 * @param cp table_name成本模块以cm开头
	 * @return
	 * @throws Exception
	 */
	public ResultModel doQueryOracleTable(CommonPage<BaseOracleTableInfo> cp) throws Exception{
		ResultModel rm = new ResultModel();
		BaseOracleTableInfo boti = cp.getObject();
		try {
			String swhere = "";
			if (boti.getTable_name()!=null && !"".equals(boti.getTable_name())) {
				swhere+=" and t.table_name like '"+boti.getTable_name()+"%'";//表名
			}
			List<BaseOracleTableInfo> list = this.getMapper(CostAcmProdMapper.class).doQueryOracleTable(swhere);		
			rm.setData(list);
			rm.setState("200");
			rm.setMsgInfo("查询成功");
		} catch (Exception e) {
			throw new Exception("查询失败，请联系管理员");
		}		
		return rm;
	}

	/**
	 * 通过表名称查询表下面的字段信息
	 * @param cp table_name表名
	 * @return
	 * @throws Exception
	 */
	public ResultModel doQueryOracleColumn(CommonPage<BaseOracleTableInfo> cp) throws Exception{
		ResultModel rm = new ResultModel();
		BaseOracleTableInfo boti = cp.getObject();
		try {
			String swhere = "";
			if (boti.getTable_name()!=null && !"".equals(boti.getTable_name())) {
				swhere+=" and t.table_name = '"+boti.getTable_name()+"'";//表名
			}
			if (boti.getColumn_name()!=null && !"".equals(boti.getColumn_name())) {
				swhere+=" and t.column_name like '%"+boti.getColumn_name()+"'";//列名
			}
			List<BaseOracleTableInfo> list = this.getMapper(CostAcmProdMapper.class).doQueryOracleColumn(swhere);		
			rm.setData(list);
			rm.setState("200");
			rm.setMsgInfo("查询成功");
		} catch (Exception e) {
			throw new Exception("查询失败，请联系管理员");
		}		
		return rm;
	}
	
	/**
	 * 查询用户的授权角色
	 * @param cp
	 * @return
	 * @throws Exception
	 */
	public ResultModel doQuerySysRole(CommonPage<BaseDstItem> cp) throws Exception{
		ResultModel rm = new ResultModel();
		try {
	        List<BaseDstItem> list = this.getMapper(CostAcmProdMapper.class).doQuarySysRole();
			rm.setData(list);
			rm.setState("200");
			rm.setMsgInfo("查询成功");
		} catch (Exception e) {
			throw new Exception("查询失败，请联系管理员"+e.getMessage());
		}	
		return rm;
	}
	
	/**
	 * 成本核算合法性检查
	 * @param cp  prd_num成本期间
	 * @return
	 * @throws Exception
	 */
	public ResultModel doExamBaseCptIndex(CommonPage<BaseCptIndex> cp) throws Exception{
		ResultModel rm = new ResultModel();
		
		BaseCptIndex BCI = new BaseCptIndex();
		String prd_num = cp.getMemo1();
		BCI.setValid_flg("1");
		List<BaseCptIndex> bciList = this.getMapper(BaseCptIndexMapper.class).findWithCondition(BCI, null, "cpt_index", 0, 0);
		if (bciList==null || bciList.size()<=0) {
			throw new Exception("未找到成本核算顺序数据");
		}
				
		for (BaseCptIndex bci : bciList) {			
			if ("0".equals(bci.getIs_auto_cpt())) {//是否检验审核(0检查、1核算)【检查】
				bci.setCpt_state("1");//开始默认检查成功							
				if ("1".equals(bci.getIs_check_judge())) {	//是否检验判断【是】				
					if (bci.getTable_name()==null||"".equals(bci.getTable_name())) {
						bci.setCpt_state("0");//核算不成功
						bci.setMemo("检查失败，未找到检查项目【"+bci.getCpt_item_name()+"】的分配数据源");
					}else {					
						Long count = 0l;				
						if ("1".equals(bci.getIs_dst_item())) {
							//如果是【分配项目】，查询分配项目对应的基础信息				
							BaseDstItem bdi = this.getMapper(BaseDstItemMapper.class).findById(bci.getDst_item_code());
							if (bdi==null) {
								bci.setCpt_state("0");//核算不成功
								bci.setMemo("检查失败，未找到检查项目【"+bci.getCpt_item_name()+"】的分配目标【"+bci.getDst_item_name()+"】对应的分配项目基础信息");
							}else {
								//判断【是否检验审核】
								if ("1".equals(bci.getIs_check_audit())) {
									count = this.getMapper(BaseCptIndexMapper.class).doQuaryTableBy(bci.getTable_name(), prd_num, "1",bci.getDst_item_code());
								}else if ("0".equals(bci.getIs_check_audit())) {
									count = this.getMapper(BaseCptIndexMapper.class).doQuaryTableBy(bci.getTable_name(), prd_num, "0",bci.getDst_item_code());
								}							
							}
						}else if ("0".equals(bci.getIs_dst_item())) {
							//如果不是【分配项目】，则查询数据源表的
							//判断【是否检验审核】
							if ("1".equals(bci.getIs_check_audit())) {
								count = this.getMapper(BaseCptIndexMapper.class).doQuaryTableBy(bci.getTable_name(), prd_num, "1",null);
							}else if ("0".equals(bci.getIs_check_audit())) {
								count = this.getMapper(BaseCptIndexMapper.class).doQuaryTableBy(bci.getTable_name(), prd_num, "0",null);
							}
						}
						if (count<=0) {
							bci.setCpt_state("0");//核算不成功
							bci.setMemo("检查失败，未找到检查项目【"+bci.getCpt_item_name()+"】中存在成本期间【"+prd_num+"】【"+bci.getTable_comment()+"】的数据");
						}										
					}
				}			
			}
		}
		//2.新增合法性检查历史记录
		CommonPage<BaseCptIndex> cp2 = new CommonPage<BaseCptIndex>();
		cp2.setObjectList(bciList);
		cp2.setMemo1(prd_num);//成本期间
		this.getBean(BaseCptHistoryServiceImpl.class).doInsertBaseCptHistory(cp2);
		//返回成功或失败给前端
		rm.setData(bciList);
		rm.setState("200");
		rm.setMsgInfo("检查结束");
		return rm;
	}
	
	/**
	 * 合法性的核算
	 * @param cp memo1:里面传成本期间
	 * @return
	 * @throws Exception
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel doInsertMiddleTable(CommonPage<BaseCptIndex> cp) throws Exception{
		ResultModel rm = new ResultModel();		
		List<String> msgList = new ArrayList<String>();
		String prd_num = cp.getMemo1();//成本期间
		//0.判断成本期间最新的一次检查是否检查成功
		BaseCptHistory bch = new BaseCptHistory();
		bch.setPrd_num(prd_num);//memo1传成本期间
		String cpt_date = this.getMapper(BaseCptIndexMapper.class).doQuaryMaxCptDate(bch);
		if (cpt_date==null || "".equals(cpt_date)) {
			throw new Exception("成本期间【"+prd_num+"】还未检查,请先检查");
		}
		bch.setCpt_date(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(cpt_date));
		bch.setCpt_state("0");
		int count = this.getMapper(BaseCptHistoryMapper.class).count(bch);
		if (count > 0) {
			throw new Exception("成本期间【"+prd_num+"】的最新检查历史中存在检查失败的检查项目");
		}
		
		//1、生成产量明细中间表
		CommonPage<CmReportProdDetail> cp1 = new CommonPage<CmReportProdDetail>();
		CmReportProdDetail rpd = new CmReportProdDetail();
		rpd.setPrd_num(prd_num);
		cp1.setObject(rpd);
		ResultModel rm1 = this.getBean(CmReportProdDetailServiceImpl.class).doInsertCmReportProdDetail(cp1);
		if (!"200".equals(rm1.getState())) {
			throw new Exception("1、生成产量明细中间表失败");
		}
		msgList.add("1、生成产量明细中间表成功。");
		
		//2、生成产量计算中间表
		CommonPage<CmReportProdMiddle> cp2 = new CommonPage<CmReportProdMiddle>();
		CmReportProdMiddle rpm = new CmReportProdMiddle();
		rpm.setPrd_num(prd_num);
		cp2.setObject(rpm);
		ResultModel rm2 = this.getBean(CmReportProdMiddleServiceImpl.class).doInsertCmReportProdMiddle(cp2);
		if (!"200".equals(rm2.getState())) {
			throw new Exception("2、生成产量计算中间表失败");
		}
		msgList.add("2、生成产量计算中间表成功。");
		
		//3、生成成本计算中间表
		CommonPage<CmReportCostMiddle> cp3 = new CommonPage<CmReportCostMiddle>();
		CmReportCostMiddle rcm = new CmReportCostMiddle();
		rcm.setPrd_num(prd_num);
		cp3.setObject(rcm);
		ResultModel rm3 = this.getBean(CmReportCostMiddleServiceImpl.class).doInsertCmReportCostMiddle(cp3);
		if (!"200".equals(rm3.getState())) {
			throw new Exception("3、生成成本计算中间表失败");
		}
		msgList.add("3、生成成本计算中间表成功。");
		
		rm.setState("200");
		rm.setData(msgList);
		return rm;
	}
	
	/**
	 * 合法性的撤销核算
	 * @param cp
	 * @return
	 * @throws Exception
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel doDeleteMiddleTable(CommonPage<BaseCptIndex> cp) throws Exception{
		ResultModel rm = new ResultModel();		
		
		//成本期间
		String prd_num = cp.getMemo1();
		BaseFiscalPeriodD b = this.getMapper(BaseFiscalPeriodDMapper.class).findById(prd_num);
		if (b==null) {
			throw new Exception("请传入成本期间");
		}
		//1.判断是否生成加工成本统计报表
		CmReportProdProcess crpp = new CmReportProdProcess();
		crpp.setPrd_num(prd_num);
		int count = this.getMapper(CmReportProdProcessMapper.class).count(crpp);
		if (count > 0) {
			throw new Exception("成本期间【"+prd_num+"】已生成【加工成本统计报表】，无法撤销核算");
		}
		//2.判断是否生成材料成本统计报表
		CmReportProdMat crpm = new CmReportProdMat();
		crpm.setPrd_num(prd_num);
		int count2 = this.getMapper(CmReportProdMatMapper.class).count(crpm);
		if (count2 > 0) {
			throw new Exception("成本期间【"+prd_num+"】已生成【材料成本统计报表】，无法撤销核算");
		}
		//3.判断是否生成产品成本统计报表
		CmReportProdCost crpc = new CmReportProdCost();
		crpc.setPrd_num(prd_num);
		int count3 = this.getMapper(CmReportProdCostMapper.class).count(crpc);
		if (count3 > 0) {
			throw new Exception("成本期间【"+prd_num+"】已生成【产品成本统计报表】，无法撤销核算");
		}
		//4.判断是否生成生产成本统计报表
		CmReportProdTotal crpt = new CmReportProdTotal();
		crpt.setPrd_num(prd_num);
		int count4 = this.getMapper(CmReportProdTotalMapper.class).count(crpt);
		if (count4 > 0) {
			throw new Exception("成本期间【"+prd_num+"】已生成【生产成本统计报表】，无法撤销核算");
		}
		//5.判断是否生成产品收发存报表
		CmReportProdIos crpi = new CmReportProdIos();
		crpi.setPrd_num(prd_num);
		int count5 = this.getMapper(CmReportProdIosMapper.class).count(crpi);
		if (count5 > 0) {
			throw new Exception("成本期间【"+prd_num+"】已生成【产品收发存报表】，无法撤销核算");
		}
		
		//6.删除产量明细中间表
		CmReportProdDetail rpd = new CmReportProdDetail();
		rpd.setPrd_num(prd_num);
		this.getMapper(CmReportProdDetailMapper.class).doDeleteCmReportProdDetail(rpd);
		
		//7.删除产量计算中间表
		CmReportProdMiddle rpm = new CmReportProdMiddle();
		rpm.setPrd_num(prd_num);
		this.getMapper(CmReportProdMiddleMapper.class).doDeleteCmReportProdMiddle(rpm);
		
		//8.删除成本计算中间表
		CmReportCostMiddle rcm = new CmReportCostMiddle();
		rcm.setPrd_num(prd_num);
		this.getMapper(CmReportCostMiddleMapper.class).doDeleteCmReportCostMiddle(rcm);
		
		rm.setState("200");
		rm.setMsgInfo("撤销核算成功");
		return rm;
	}
	
}
