/***文档注释***********************************************
 * 作者            ：
 * 创建日期     ：2019-07-06
 * 描述            ：产品收发存表
 * 注意事项     ：
 * 遗留BUG   ：
 * 修改日期     ：
 * 修改人员     ：
 * 修改内容     ：
***********************************************************/
package market.Cm.impl;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import market.Cm.mapper.BaseFiscalPeriodDMapper;
import market.Cm.mapper.CmReportProdIosMapper;
import market.Cm.mapper.CostAcmProdMapper;
import market.Cm.service.CmReportProdIosService;
import market.Cm.vo.BaseFiscalPeriodD;
import market.Cm.vo.CmReportProdIos;
import market.Cm.vo.CostAcmProd;
import market.Com.mapper.PbModelDbMapper;
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="CmReportProdIosService")
public class CmReportProdIosServiceImpl extends BaseServiceImpl<CmReportProdIos,Object> implements CmReportProdIosService {
	
	/**
	 * 产品收发存统计：查询功能
	 * @param cp object[选传 item_code,prd_num,org_code,org_name,valid_flg,audit_flg等]
	 * @return
	 * @throws Exception
	 */
	public ResultModel doQueryCmReportProdIos(CommonPage<CmReportProdIos> cp) throws Exception{
		ResultModel rm  = new ResultModel();
		CmReportProdIos rpi = cp.getObject();
		try {
			List<CmReportProdIos> list = this.getMapper(CmReportProdIosMapper.class).doQueryCmReportProdIos(rpi);
			rm.setState("200");
			rm.setData(list);
		} catch (Exception e) {
			throw new Exception("查询失败，请联系管理员");
		}
		return rm;
	}
	
	/**
	 * 产品收发存统计明细：查询功能
	 * @param cp
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("rawtypes")
	public ResultModel doQueryCmReportProdIosDetail(CommonPage<CmReportProdIos> cp) throws Exception{
		ResultModel rm  = new ResultModel();
		CmReportProdIos rpi = cp.getObject();
		try {
			List<HashMap> list = this.getMapper(CmReportProdIosMapper.class).doQueryCmReportProdIosDetail(rpi);
			rm.setState("200");
			rm.setData(list);
		} catch (Exception e) {
			throw new Exception("查询失败，请联系管理员");
		}
		return rm;
	}

	/**
	 * 产品收发存统计：核算功能【业务模式order_model,产品状态prd_state】
	 * @param cp
	 * @return
	 * @throws Exception
	 */
	@Transactional(value = "tm", rollbackFor = Exception.class)
	public ResultModel doInsertCmReportProdIos(CommonPage<CmReportProdIos> cp) throws Exception{
		ResultModel rm = new ResultModel();
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		Date now = new Date();
		CmReportProdIos rpi = cp.getObject();
		BaseFiscalPeriodD bfpd = this.getMapper(BaseFiscalPeriodDMapper.class).findById(rpi.getPrd_num());
		if (bfpd==null) {
			throw new Exception("成本期间传递有误");
		}
		//判断当前成本期间是否核算
		CmReportProdIos RPI = new CmReportProdIos();
		RPI.setPrd_num(rpi.getPrd_num());
		int count = this.getMapper(CmReportProdIosMapper.class).count(RPI);
		if (count > 0) {
			throw new Exception("成本期间【"+rpi.getPrd_num()+"】的产品收发存统计已经核算");
		}

		//1.查询【投入产出归集表】获取本期增加
		CostAcmProd cap = new CostAcmProd();
		cap.setPrd_num(rpi.getPrd_num());
		List<CostAcmProd> capList = this.getMapper(CostAcmProdMapper.class).doQuaryCcapForCrpi(cap);
		if (capList==null || capList.size()<=0) {
			throw new Exception("未找到【投入产出归集】数据");
		}
		for (CostAcmProd CAP : capList) {
			CmReportProdIos crpi = new CmReportProdIos();
			crpi.setObject_code(CAP.getObject_code());//成本对象
			crpi.setObject_name(CAP.getObject_name());
			crpi.setItem_code(CAP.getItem_code());//成本项目
			crpi.setItem_name(CAP.getItem_name());
			crpi.setOrg_code(CAP.getOrg_code());//成本组织
			crpi.setOrg_name(CAP.getOrg_name());
			crpi.setPrd_num(CAP.getPrd_num());//成本期间
			crpi.setItem_name_type(CAP.getParent_item_name());//产品类别:[合金钢/弹簧钢]
			crpi.setOrder_model(CAP.getOrder_model());//业务模式(A自制，B委托)
			crpi.setProd_state(CAP.getProd_state());//产品状态(A产成品，B中间品，C在制品)
			//期初
			crpi.setStart_wgt(0d);//期初数量
			crpi.setStart_price(0d);//期初单价
			crpi.setStart_amount(0d);//期初成本			
			//本期增加(产量)
			crpi.setInput_wgt(CAP.getOutput_wgt_value()==null?0:CAP.getOutput_wgt_value());//本期入库数量(产出量)
			crpi.setInput_amount(CAP.getAmount_value()==null?0:CAP.getAmount_value());//本期入库成本
			if (crpi.getInput_wgt()!=0) {				
				crpi.setInput_price(crpi.getInput_amount()/crpi.getInput_wgt());//本期入库单价(单位成本)
			}
			//本期减少默认为0，本期期末默认是本期增加
			crpi.setOut_amount(0d);
			crpi.setOut_price(0d);
			crpi.setOut_wgt(0d);
			crpi.setEnd_amount(crpi.getInput_amount());
			crpi.setEnd_price(crpi.getInput_price());
			crpi.setEnd_wgt(crpi.getInput_wgt());
			
			crpi.setMemo(CAP.getMemo());
			crpi.setValid_flg("1");
			crpi.setAudit_flg("0");
			crpi.setCreate_man(userName);
			crpi.setCreate_time(now);
			this.getMapper(CmReportProdIosMapper.class).insert(crpi);			
		}
		
		//2.获取本期减少数据
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String startTime = df.format(bfpd.getStr_date());
		String endTime = df.format(bfpd.getEnd_date());
		List<CmReportProdIos> outIosList = this.getMapper(CmReportProdIosMapper.class).doQueryOutCmReportProdIos(RPI,startTime,endTime);
		if (outIosList!=null && outIosList.size()>0) {
			for (CmReportProdIos outIos : outIosList) {
				CmReportProdIos isIn= new CmReportProdIos();
				isIn.setObject_code(outIos.getObject_code());
				isIn.setItem_code(outIos.getItem_code());
				isIn.setOrg_code(outIos.getOrg_code());
				isIn.setPrd_num(rpi.getPrd_num());
				isIn.setItem_name_type(outIos.getItem_name_type());
				isIn.setOrder_model(outIos.getOrder_model());
				isIn.setProd_state(outIos.getProd_state());
				List<CmReportProdIos> isInList = this.getMapper(CmReportProdIosMapper.class).find(isIn, 0, 0);
				if (isInList!=null && isInList.size()>0) {
					//如果成本期间存在本期增加记录，则修改本期减少，和本期期末
					isIn = isInList.get(0);
					//本期减少
					isIn.setOut_wgt(outIos.getOut_wgt()==null?0:outIos.getOut_wgt());
					isIn.setOut_price(outIos.getOut_price()==null?0:outIos.getOut_price());
					isIn.setOut_amount(outIos.getOut_amount()==null?0:outIos.getOut_amount());
					//期末=(期初+本期增加-本期减少)
					isIn.setEnd_wgt(isIn.getStart_wgt()-isIn.getOut_wgt()+isIn.getInput_wgt());//期末数量
					isIn.setEnd_amount(isIn.getStart_amount()-isIn.getOut_amount()+isIn.getInput_amount());//期末成本
					if (isIn.getEnd_wgt()!=0) {
						isIn.setEnd_price(isIn.getEnd_amount()/isIn.getEnd_wgt());//期末单价				
					}
					this.getMapper(CmReportProdIosMapper.class).doUpdateCmReportProdIos(isIn);
				}else {
					//新增数据
					//期初
					outIos.setStart_wgt(0d);//期初数量
					outIos.setStart_price(0d);//期初单价
					outIos.setStart_amount(0d);//期初成本
					outIos.setInput_amount(0d);
					outIos.setInput_wgt(0d);
					outIos.setInput_price(0d);
					outIos.setOut_amount(outIos.getOut_amount()==null?0:outIos.getOut_amount());
					outIos.setOut_price(outIos.getOut_price()==null?0:outIos.getOut_price());
					outIos.setOut_wgt(outIos.getOut_wgt()==null?0:outIos.getOut_wgt());
					//期末=(期初+本期增加-本期减少)
					outIos.setEnd_wgt(outIos.getStart_wgt()-outIos.getOut_wgt()+outIos.getInput_wgt());//期末数量
					outIos.setEnd_amount(outIos.getStart_amount()-outIos.getOut_amount()+outIos.getInput_amount());//期末成本
					if (outIos.getEnd_wgt()!=0) {
						outIos.setEnd_price(outIos.getEnd_amount()/outIos.getEnd_wgt());//期末单价				
					}
					outIos.setPrd_num(rpi.getPrd_num());
					outIos.setValid_flg("1");
					outIos.setAudit_flg("0");
					outIos.setCreate_man(userName);
					outIos.setCreate_time(now);
					this.getMapper(CmReportProdIosMapper.class).insert(outIos);
				}
			}
		}
		
		//3.设置期初数据
		SimpleDateFormat sd = new SimpleDateFormat("yyyyMM");
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(sd.parse(rpi.getPrd_num()));
		calendar.add(Calendar.MONTH, -1);
		String startPrd_num = sd.format(calendar.getTime());
		//上月期末的期末重量>0的数据
		String condition = " and prd_num = '"+startPrd_num+"' and end_wgt > 0";
		List<CmReportProdIos> endList = this.getMapper(CmReportProdIosMapper.class).findWithCondition(null, condition, null, 0, 0);
		if (endList!=null && endList.size()>0) {
			for (CmReportProdIos endIos : endList) {
				CmReportProdIos isIn= new CmReportProdIos();
				isIn.setObject_code(endIos.getObject_code());
				isIn.setItem_code(endIos.getItem_code());
				isIn.setOrg_code(endIos.getOrg_code());
				isIn.setPrd_num(rpi.getPrd_num());
				isIn.setItem_name_type(endIos.getItem_name_type());
				isIn.setOrder_model(endIos.getOrder_model());
				isIn.setProd_state(endIos.getProd_state());
				List<CmReportProdIos> isInList = this.getMapper(CmReportProdIosMapper.class).find(isIn, 0, 0);
				if (isInList!=null && isInList.size()>0) {
					isIn = isInList.get(0);
					isIn.setStart_wgt(endIos.getEnd_wgt()==null?0:endIos.getEnd_wgt());
					isIn.setStart_price(endIos.getEnd_price()==null?0:endIos.getEnd_price());
					isIn.setStart_amount(endIos.getEnd_amount()==null?0:endIos.getEnd_amount());
					//期末=(期初+本期增加-本期减少)
					isIn.setEnd_wgt(isIn.getStart_wgt() - isIn.getOut_wgt() + isIn.getInput_wgt());//期末数量
					isIn.setEnd_amount(isIn.getStart_amount() - isIn.getOut_amount() + isIn.getInput_amount());//期末成本
					if (isIn.getEnd_wgt()!=0) {
						isIn.setEnd_price(isIn.getEnd_amount()/isIn.getEnd_wgt());//期末单价				
					}
					this.getMapper(CmReportProdIosMapper.class).doUpdateCmReportProdIos(isIn);
				}else {
					//新增数据(期初和期末=上月期末，本月增加和本月减少都为0)
					isIn.setObject_name(endIos.getObject_name());
					isIn.setItem_name(endIos.getItem_name());
					isIn.setOrg_name(endIos.getOrg_name());
					isIn.setStart_amount(endIos.getEnd_amount()==null?0:endIos.getEnd_amount());
					isIn.setStart_wgt(endIos.getEnd_wgt()==null?0:endIos.getEnd_wgt());
					isIn.setStart_price(endIos.getEnd_price()==null?0:endIos.getEnd_price());
					isIn.setOut_amount(0d);
					isIn.setOut_price(0d);
					isIn.setOut_wgt(0d);
					isIn.setInput_amount(0d);
					isIn.setInput_price(0d);
					isIn.setInput_wgt(0d);
					isIn.setEnd_amount(isIn.getStart_amount());
					isIn.setEnd_price(isIn.getStart_price());
					isIn.setEnd_wgt(isIn.getStart_wgt());
					isIn.setPrd_num(rpi.getPrd_num());
					isIn.setValid_flg("1");
					isIn.setAudit_flg("0");
					isIn.setCreate_man(userName);
					isIn.setCreate_time(now);
					this.getMapper(CmReportProdIosMapper.class).insert(isIn);
				}
			
			}
		}
		rm.setState("200");
		rm.setMsgInfo("产品收发存统计核算成功");
		return rm;
	}
	
	/**
	 * 产品收发存统计：审核及反审
	 * @param cp object[org_code成本组织 prd_num成本期间] memo1[1审核 0反审]
	 * @return
	 * @throws Exception
	 */
	public ResultModel doChangeCmReportProdIosAuditFlg(CommonPage<CmReportProdIos> cp) throws Exception{
		String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
		ResultModel rm = new ResultModel();
		String opr = cp.getMemo1();
		String type= cp.getMemo2();
		CmReportProdIos rpi = cp.getObject();
		if (rpi.getPrd_num()==null || "".equals(rpi.getPrd_num())) {
			throw new Exception("请传入成本期间");
		}
		Date now = new Date();
		//通过成本期间和成本组织进行【审核】和【反审】
		CmReportProdIos RPI = new CmReportProdIos();
		RPI.setOrder_model(rpi.getOrder_model());
		RPI.setProd_state(rpi.getProd_state());
		RPI.setPrd_num(rpi.getPrd_num());
		RPI.setAudit_flg("1".equals(opr)?"1":"0");//
		List<CmReportProdIos> rpiList = this.getMapper(CmReportProdIosMapper.class).find(RPI, 0, 0);
		if (rpiList!=null && rpiList.size()>0) {
			throw new Exception("【"+type+"】的成本期间【"+rpi.getPrd_num()+"】中存在"+("1".equals(opr)?"已审核":"未审核")+"的数据");
		}
		rpi.setAudit_flg(opr);
		rpi.setAudit_man(userName);
		rpi.setAudit_time(now);
		this.getMapper(CmReportProdIosMapper.class).doChangeCmReportProdIosAuditFlg(rpi);	
		rm.setState("200");
		rm.setMsgInfo("【"+type+"】的成本期间【"+rpi.getPrd_num()+"】"+("0".equals(cp.getMemo1())?"反审":"审核") + "操作成功");
		return rm;
	}
	
	/**
	 * 产品收发存统计：删除
	 * @param cp
	 * @return
	 * @throws Exception
	 */
	public ResultModel doDeleteCmReportProdIos(CommonPage<CmReportProdIos> cp) throws Exception{
		ResultModel rm = new ResultModel();
		CmReportProdIos rpi = cp.getObject();
		if (rpi.getPrd_num()==null || "".equals(rpi.getPrd_num())) {
			throw new Exception("请传入成本期间");
		}
		//判断是否后台进行了调整
		String condition = " and prd_num = '"+rpi.getPrd_num()+"' and memo is not null";
		int count = this.getMapper(CmReportProdIosMapper.class).countWithCondition(null, condition);
		if (count>0) {
			String userName = (String) this.getSession().getAttribute(HomeService.SESSION_USER_NAME);
			if (!"admin".equals(userName)) {
				throw new Exception("成本期间【"+rpi.getPrd_num()+"】的产品收发存统计已经进行后台调整，请联系管理员进行处理");
			}
		}
		CmReportProdIos crpi = new CmReportProdIos();
		crpi.setPrd_num(rpi.getPrd_num());
		this.getMapper(CmReportProdIosMapper.class).doDeleteCmReportProdIos(crpi);		
		rm.setState("200");
		rm.setMsgInfo("删除产品收发存统计成功");
		return rm;		
	}
	
	/**
	 * 业务利润分析表
	 * @param cp
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings({ "rawtypes" })
	public ResultModel doQuaryProfitAnalysis(CommonPage<CostAcmProd> cp) throws Exception{
		ResultModel rm = new ResultModel();
		CostAcmProd cap = cp.getObject();
		String startTime = cp.getStartTime();
		String endTime = cp.getEndTime();
		String condition = "";
		if (cap.getItem_code()!=null && !"".equals(cap.getItem_code())) {
			condition += " and bci.item_code = '"+cap.getItem_code()+"'";
		}
		if (cap.getItem_name()!=null && !"".equals(cap.getItem_name())) { //牌号
			condition += " and bci.item_name like '%"+cap.getItem_name()+"%'";
		}
		if (cap.getMat_coil_no()!=null && !"".equals(cap.getMat_coil_no())) {	//原料卷号
			condition += " and ypd.materailcoilno like '%"+cap.getMat_coil_no()+"%'";
		}
		if (cap.getOrder_model()!=null && !"".equals(cap.getOrder_model())) {
			if ("贸易".equals(cap.getOrder_model())) {
				condition += " and sfsb.settle_bill_no like 'Y%'";
			}else if ("委托".equals(cap.getOrder_model())) {
				condition += " and sfsb.settle_bill_no like 'J%'";
			}else if ("自制".equals(cap.getOrder_model())) {
				condition += " and (sfsb.settle_bill_no like 'N%' or sfsb.settle_bill_no like 'L%')";
			}
		}
		if (startTime!=null && !"".equals(startTime)) {
			condition += " and sfsb.update_time >= to_date('"+startTime+" 00:00:00','yyyy-MM-dd HH24:mi:ss')";
		}
		if (endTime!=null && !"".equals(endTime)) {
			condition += " and sfsb.update_time <= to_date('"+endTime+" 23:59:59','yyyy-MM-dd HH24:mi:ss')";
		}
		List<HashMap> list = this.getMapper(CmReportProdIosMapper.class).doQuaryProfitAnalysis(condition);
		rm.setState("200");
		rm.setData(list);
		return rm;
	} 
	
	/**
	 * 报表：产品成本明细表
	 * @param cp
	 * @return
	 * @throws Exception
	 */
	public ResultModel doQuaryCcapForReportDetail(CommonPage<CostAcmProd> cp) throws Exception{
		ResultModel rm  = new ResultModel();
		CostAcmProd cap = cp.getObject();
		try {
			if (cap.getPrd_num()==null || "".equals(cap.getPrd_num())) {
				throw new Exception("请传入成本期间");
			}
			List<CostAcmProd> list = this.getMapper(CostAcmProdMapper.class).doQuaryCcapForReportDetail(cap);
			rm.setState("200");
			rm.setData(list);
		} catch (Exception e) {
			throw new Exception("查询失败，请联系管理员");
		}
		return rm;
	}
	
	/**
	 * 转库导出
	 * @param cp
	 * @return
	 * @throws Exception
	 */
	public ResultModel doExportMoveInfo(CommonPage<CostAcmProd> cp) throws Exception{
		ResultModel rm  = new ResultModel();
		CostAcmProd cap = cp.getObject();
		try {
			if (cap.getPrd_num()==null || "".equals(cap.getPrd_num())) {
				throw new Exception("请传入成本期间");
			}
			String sql = "select distinct com_get_basename(t.storageattr) storageattr, com_get_basename(t.restorageattr) restorageattr,"
					+ " cbs.steel_type,cbs.steel_name, t.coilno, com_get_basename(ypd.object_attr) object_attr, ypd.factweight/1000 factweight"
					+ " from ydm_product_move t "
					+ " left join ydm_product_detail ypd on t.coilno = ypd.coilno "
					+ " left join com_base_steel cbs on t.judgesteelcode = cbs.steel_code "
					+ " where to_char(t.movedate,'yyyyMM') = '"+cap.getPrd_num()+"' "
					+ " and ((t.storageattr = '500202' and t.restorageattr = '500203') or ((t.storageattr = '500203' and t.restorageattr = '500202'))) "
					+ " order by com_get_basename(t.storageattr),cbs.steel_type,cbs.steel_name,t.coilno";	
			rm.setState("200");
			rm.setData(this.getMapper(PbModelDbMapper.class).doQueryHashMap(sql));
		} catch (Exception e) {
			throw new Exception("查询失败，请联系管理员");
		}
		return rm;
	}
	
}
