package nc.itf.fa.servlet;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import nc.bs.dao.BaseDAO;
import nc.bs.dao.DAOException;
import nc.bs.framework.adaptor.IHttpServletAdaptor;
import nc.bs.framework.common.InvocationInfoProxy;
import nc.bs.framework.common.NCLocator;
import nc.bs.framework.comn.NetStreamContext;
import nc.bs.framework.server.ISecurityTokenCallback;
import nc.bs.hz.utils.BillInfoQueryUtil;
import nc.bs.hz.utils.SafeObject;
import nc.bs.hz.utils.SendUtil;
import nc.cmp.utils.BillcodeGenerater;
import nc.itf.fa.byzlog.IbyzLogRcord;
import nc.itf.fa.prv.IAlter;
import nc.itf.fa.prv.IReduce;
import nc.itf.uap.pf.IPFBusiAction;
import nc.itf.uap.pf.IplatFormEntry;
import nc.jdbc.framework.SQLParameter;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.vo.am.common.TransportBillVO;
import nc.vo.fa.alter.AlterVO;
import nc.vo.fa.asset.AssetVO;
import nc.vo.fa.assetcard.CardVO;
import nc.vo.fa.assetcard.CardhistoryVO;
import nc.vo.fa.byzLogVO.ByzLogRcordVO;
import nc.vo.fa.reduce.ReduceBodyVO;
import nc.vo.fa.reduce.ReduceHeadVO;
import nc.vo.fa.reduce.ReduceVO;
import nc.vo.org.FinanceOrgVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pub.lang.UFDate;
import nc.vo.pub.lang.UFDateTime;
import nc.vo.pub.lang.UFDouble;
import nc.vo.uif2.LoginContext;
import nccloud.framework.service.ServiceLocator;
import nccloud.pub.ampub.script.IAppScript4Cloud;
import nccloud.pubitf.fa.maintain.reduce.IReduce4Cloud;
import nccloud.pubitf.riart.pflow.ICloudScriptPFlowService;
import uap.json.JSONArray;
import uap.json.JSONObject;

public class ByzSysAmReduceServlet implements IHttpServletAdaptor {

	// 获取数据库操作对象
	private BaseDAO baseDAO;
	
	@Override
	public void doAction(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//byz日志vo
		ISecurityTokenCallback tc = NCLocator.getInstance().lookup(ISecurityTokenCallback.class);
		  byte[] token = tc.token("__system".getBytes(), "NC".getBytes());
		  NetStreamContext.setToken(token);
		ByzLogRcordVO byzLogRcordVO = null;
//		NCLocator.getInstance().lookup(ISecurityTokenCallback.class).token("NCSystem".getBytes(), "pfxx".getBytes());
		com.alibaba.fastjson.JSONObject resultjson = new com.alibaba.fastjson.JSONObject();
		String reqJson = requestJson(req);
		

		try {
            			
			//byz日志
			byzLogRcordVO = new ByzLogRcordVO();
			byzLogRcordVO.setItf_type("固定资产减少");
			byzLogRcordVO.setByztonccparam(SendUtil.unicodeToString(reqJson));
			byzLogRcordVO.setItfaddress(req.getRequestURI());
			byzLogRcordVO.setItfclass(this.getClass().getName());
			
			

			JSONObject reqJsonObj = new JSONObject(reqJson); 

			JSONObject dataJSONObject = reqJsonObj.getJSONObject("data");

			// 获取表头数据并设置进vo
			JSONObject headJSONObject = dataJSONObject.getJSONObject("head");
			// 初始化
			BillInfoQueryUtil.initEnvironment("0001H810000000000HS2", new UFDate(headJSONObject.getString("business_date")));
			BillInfoQueryUtil.initSysBilltypeCache(new String[] { "HF" });
			ReduceHeadVO reduceHeadVO = new ReduceHeadVO();
			reduceHeadVO.setPk_org(headJSONObject.getString("pk_org"));
			reduceHeadVO.setPk_group("0001H810000000000HS2");
			reduceHeadVO.setDef13(headJSONObject.getString("legal_person"));
			reduceHeadVO.setBusiness_date(new UFDate(headJSONObject.getString("business_date")));
//			reduceHeadVO.setBill_status(Integer.valueOf(headJSONObject.getString("bill_status")));
			reduceHeadVO.setBill_status(0);
			reduceHeadVO.setReason(headJSONObject.getString("reason"));
			
			String currencyPk = BillInfoQueryUtil.getBdcurrtypenameByName(headJSONObject.getString("pk_currency"));
			if(null == currencyPk || "".equals(currencyPk)) {
				throw new Exception("币种不合法");
			}
			reduceHeadVO.setPk_currency(currencyPk);
			
			reduceHeadVO.setRemark(headJSONObject.getString("remark"));
			reduceHeadVO.setDef10(headJSONObject.getString("def1"));
			//校验唯一性
			selectOnlyID(headJSONObject.getString("def2"));
			reduceHeadVO.setDef11(headJSONObject.getString("def2"));
//			Boolean a = headJSONObject.has("def4");
//			Boolean a = (null == headJSONObject.getString("def4"));
			reduceHeadVO.setDef4(headJSONObject.has("def4") ? headJSONObject.getString("def4") : "");
			reduceHeadVO.setDef5(headJSONObject.has("def5") ? headJSONObject.getString("def5") : "");
//			reduceHeadVO.setBillmaker(headJSONObject.has("billmaker") ? headJSONObject.getString("billmaker") : "");
			reduceHeadVO.setBillmaker(BillInfoQueryUtil.getPK_syscreater());
			if (headJSONObject.has("billmaketime")) {
				reduceHeadVO.setBillmaketime(new UFDateTime(headJSONObject.getString("billmaketime")));
			}
			reduceHeadVO.setCreator(BillInfoQueryUtil.getPK_syscreater());
			reduceHeadVO.setCreationtime(new UFDateTime(headJSONObject.getString("creationtime")));
//			reduceHeadVO.setModifier(headJSONObject.getString("modifier"));
//			reduceHeadVO.setModifiedtime(new UFDateTime(headJSONObject.getString("modifiedtime")));

			reduceHeadVO.setTransi_type("HF-01");
			reduceHeadVO.setPk_transitype("0001H81000000000DN9N");
			reduceHeadVO.setBill_type("HF");
			reduceHeadVO.setBill_type_src("HF");
			//获取并设置账簿
			reduceHeadVO.setPk_accbook(getAccountingbook(reduceHeadVO.getPk_org()));
			reduceHeadVO.setPk_accbook_scale(getAccountingbook(reduceHeadVO.getPk_org()));
			String billcode = (new BillcodeGenerater()).getBillCode("HF", reduceHeadVO.getPk_group(), reduceHeadVO.getPk_org(), null, null);
			reduceHeadVO.setBill_code(billcode);
			

			FinanceOrgVO pk_org_v = BillInfoQueryUtil.selectOrg((String) reduceHeadVO.getPk_org());
			reduceHeadVO.setPk_org_v((String) pk_org_v.getPk_vid());
			
			byzLogRcordVO.setVbillcode(reduceHeadVO.getBill_code());

			// 获取表体数据列表并设置进vo列表
			List<ReduceBodyVO> bodyList = new ArrayList<ReduceBodyVO>();

			JSONArray bodyJSONArray = dataJSONObject.getJSONArray("bodys");

			List<JSONObject> bodyJsonList = bodyJSONArray.getArrayList();
			for (JSONObject bodyJSONObject : bodyJsonList) {
				ReduceBodyVO reduceBodyVO = new ReduceBodyVO();
				reduceBodyVO.setPk_org(reduceHeadVO.getPk_org());
				reduceBodyVO.setPk_org_v(reduceHeadVO.getPk_org_v());
				//获取折旧相关信息vo并设置折旧信息
				CardhistoryVO cardhistoryVO= BillInfoQueryUtil.getFaCardHistory(bodyJSONObject.getString("pk_card"));
				//add by djy20220402 算实际的累计折旧
				Map<String, Object> mapdep=new HashMap<String, Object>();
				String[] pks=new String[] {bodyJSONObject.getString("pk_card")};
				mapdep=BillInfoQueryUtil.handlerDep(pks,reduceHeadVO.getPk_group(),
						reduceHeadVO.getPk_org(),reduceHeadVO.getPk_accbook(),reduceHeadVO.getBusiness_date(),UFBoolean.FALSE);
				if(mapdep.get("simulateAccudep")==null||
						((HashMap)mapdep.get("simulateAccudep")).get(bodyJSONObject.getString("pk_card"))==null)
					throw new Exception("计算累计折旧有误，请联系管理员");			
				cardhistoryVO.setAccudep((UFDouble) ((HashMap)mapdep.get("simulateAccudep")).get(bodyJSONObject.getString("pk_card")));
				reduceBodyVO.setSimulatedep((UFDouble) ((HashMap)mapdep.get("simulateDepamount")).get(bodyJSONObject.getString("pk_card")));
				
				AssetVO assetVO= BillInfoQueryUtil.getFaCard(bodyJSONObject.getString("pk_card"));
				if (cardhistoryVO != null && assetVO != null) {
					//本币原值
					reduceBodyVO.setRed_localoriginvalue(cardhistoryVO.getLocaloriginvalue());
					//累计折旧
					reduceBodyVO.setRed_accudep(cardhistoryVO.getAccudep());
					reduceBodyVO.setRed_predevaluate(cardhistoryVO.getPredevaluate());
					//模拟折旧，讨论后不启用
//					reduceBodyVO.setSimulatedep(cardhistoryVO.getAccudep());
					//净值
					UFDouble jz = cardhistoryVO.getLocaloriginvalue() == null ? new UFDouble("0.00")
							: cardhistoryVO.getLocaloriginvalue()
									.sub(cardhistoryVO.getAccudep() == null ? new UFDouble("0.00")
											: cardhistoryVO.getAccudep());
					//净额
					UFDouble je = jz.sub(cardhistoryVO.getPredevaluate() == null ? new UFDouble("0.00")
							: cardhistoryVO.getPredevaluate());
					reduceBodyVO.setRed_netvalue(jz);
					reduceBodyVO.setRed_netrating(je);
					reduceBodyVO.setAccudep(cardhistoryVO.getAccudep());
					reduceBodyVO.setRed_salvage(cardhistoryVO.getSalvage());
				}
				
				reduceBodyVO.setPk_card(bodyJSONObject.getString("pk_card"));
				
				//减少方式
				String reduceStylePk= BillInfoQueryUtil.getFaAddOrReduceStyle(bodyJSONObject.getString("pk_reducestyle"));
				reduceBodyVO.setPk_reducestyle(reduceStylePk);
				
				//减少原因
				String reduceReasonPk = BillInfoQueryUtil.getFaReduceReason(bodyJSONObject.getString("pk_reason"));
				reduceBodyVO.setPk_reason(reduceReasonPk);//暂时改成固定值
				
				//减少对方单位
				String cumandocPk = BillInfoQueryUtil.getUnit(bodyJSONObject.getString("pk_cumandoc"));
				reduceBodyVO.setPk_cumandoc(cumandocPk);//暂时改成固定值
				
				reduceBodyVO.setMemo(bodyJSONObject.has("memo") ? bodyJSONObject.getString("memo") : "");
//				reduceBodyVO.setRed_localoriginvalue(new UFDouble(bodyJSONObject.getString("red_localoriginvalue")));
				if (bodyJSONObject.has("red_accudep")) {
					reduceBodyVO.setRed_accudep(new UFDouble(bodyJSONObject.getString("red_accudep")));
				}
				if (bodyJSONObject.has("red_predevaluate")) {
					reduceBodyVO.setRed_predevaluate(new UFDouble(bodyJSONObject.getString("red_predevaluate")));
				}
//				if (bodyJSONObject.has("simulatedep")) {
//					reduceBodyVO.setSimulatedep(new UFDouble(bodyJSONObject.getString("simulatedep")));
//				}
				if (bodyJSONObject.has("purgerevenue")) {
					reduceBodyVO.setPurgerevenue(new UFDouble(bodyJSONObject.getString("purgerevenue")));
				}
				if (bodyJSONObject.has("purgefee")) {
					reduceBodyVO.setPurgefee(new UFDouble(bodyJSONObject.getString("purgefee")));
				}
//				if (bodyJSONObject.has("red_netvalue")) {
//					reduceBodyVO.setRed_netvalue(new UFDouble(bodyJSONObject.getString("red_netvalue")));
//				}
//				if (bodyJSONObject.has("red_netrating")) {
//					reduceBodyVO.setRed_netrating(new UFDouble(bodyJSONObject.getString("red_netrating")));
//				}
//				if (bodyJSONObject.has("red_salvage")) {
//					reduceBodyVO.setRed_salvage(new UFDouble(bodyJSONObject.getString("red_salvage")));
//				}
//				if (bodyJSONObject.has("accudep")) {
//					reduceBodyVO.setAccudep(new UFDouble(bodyJSONObject.getString("accudep")));
//				}
//				if (bodyJSONObject.has("modifiedtime")) {
//					reduceBodyVO.setTs(new UFDateTime(bodyJSONObject.getString("modifiedtime")));
//				}
				
				String currencyPk2 = BillInfoQueryUtil.getBdcurrtypenameByName(bodyJSONObject.getString("pk_currency"));
				if(null == currencyPk2 || "".equals(currencyPk2)) {
					throw new Exception("币种不合法");
				}
				reduceBodyVO.setPk_currency(currencyPk2);
				
				bodyList.add(reduceBodyVO);
			}

//			Map headMap = headJSONObject.getHashMap();
//			ReduceHeadVO reduceHeadVO = JSONObject.toJavaObject(headJSONObject, ReduceHeadVO.class);
			if (reduceHeadVO == null || bodyList == null || bodyList.size() < 1) {
				throw new Exception("请求参数为空或不合法");
			}
			
			
			InvocationInfoProxy.getInstance().setGroupId("0001H810000000000HS2");
			
			//生成减少单
			builReduceBill(reduceHeadVO, bodyList);

			
			/*
			 * 0201出售；0202盘亏；0206报废；0211其他减少方式；0212拆分与合并；如果是0201出售，则需要另外同步资产处置应收单，并确认应收的销项税，
			 * 价税合计； 如果是盘亏、报废、其他减少方式，则只需要同步生成资产减少单即可
			 */
			/*
			 * for (ReduceBodyVO reduceBodyVO : bodyList) {
			 * 
			 * 
			 * 
			 * if ("0201".equals(reduceBodyVO.getPk_reducestyle())) {
			 * builReduceBill(reduceHeadVO, reduceBodyVO); //调用应收单接口生成应收单
			 * 
			 * 
			 * }else if("0202".equals(reduceBodyVO.getPk_reducestyle())) {
			 * builReduceBill(reduceHeadVO, reduceBodyVO); }else
			 * if("0206".equals(reduceBodyVO.getPk_reducestyle())) {
			 * builReduceBill(reduceHeadVO, reduceBodyVO); }else
			 * if("0211".equals(reduceBodyVO.getPk_reducestyle())) {
			 * builReduceBill(reduceHeadVO, reduceBodyVO); }else
			 * if("0212".equals(reduceBodyVO.getPk_reducestyle())) {
			 * builReduceBill(reduceHeadVO, reduceBodyVO); }else { return; }
			 * 
			 * }
			 */
			//byz日志
			byzLogRcordVO.setPk_bill(reduceHeadVO.getPrimaryKey());
			
			
			resultjson.put("billno", reduceHeadVO.getBill_code());
			resultjson.put("billpk", reduceHeadVO.getPrimaryKey());
			resultjson.put("guid", reduceHeadVO.getDef11());
			resultjson.put("message", "固定资产减少新增成功。");
			resultjson.put("status", 1);

		} catch (Exception e) {
			// TODO Auto-generated catch block
//			String eee = e.getMessage();
			resultjson.put("message", e.getMessage());
			resultjson.put("status", 0);
//			nc.vo.pubapp.pattern.exception.ExceptionUtils.wrappBusinessException(e.toString());
		} finally {
			
			//byz日志
			byzLogRcordVO.setNcctobyzresult(SendUtil.unicodeToString(resultjson.toString()));
			responseWriter(resp, resultjson.toString());
			
			if (null != byzLogRcordVO ) {
				IbyzLogRcord byzLogRcord = (IbyzLogRcord)NCLocator.getInstance().lookup(IbyzLogRcord.class);
				try {
					byzLogRcord.RcordLogBYZ__RequiresNew(byzLogRcordVO);
				} catch (BusinessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

	}

	
	/**
	 * 生成减少单
	 * @param reduceHeadVO 表头
	 * @param bodyList 表体列表
	 * @throws BusinessException
	 */
	public void builReduceBill(ReduceHeadVO reduceHeadVO, List<ReduceBodyVO> bodyList) throws BusinessException {
		//聚合vo生成
		ReduceVO reduceVO = new ReduceVO();
		reduceVO.setParent(reduceHeadVO);
		ReduceBodyVO[]  reduceBodyVOs = bodyList.toArray(new ReduceBodyVO[bodyList.size()]);
		reduceVO.setChildrenVO(reduceBodyVOs);

		//保存提交减少单
//		IReduce reduce = (IReduce) NCLocator.getInstance().lookup(IReduce.class);
//		reduce.insert(null, reduceVO);
		
		LoginContext context = new LoginContext();
		context.setPk_group(InvocationInfoProxy.getInstance().getGroupId());
		context.setPk_loginUser(InvocationInfoProxy.getInstance().getUserId());
		NCLocator.getInstance().lookup(IReduce4Cloud.class).save(reduceVO);
//		NCLocator.getInstance().lookup(IReduce.class).insert(context, reduceVO);
		String pk = reduceVO.getPrimaryKey();
		ReduceVO[] sReduceVO = NCLocator.getInstance().lookup(IReduce.class).queryReduceVOByPk(pk);
		boolean approvalProcess = nccloud.bs.pub.pf.CloudPfUtil.hasApproveflowDef("HF-01", sReduceVO[0]);
		if (!approvalProcess) {// 如果没有审批流
			IPFBusiAction baService = (IPFBusiAction) NCLocator.getInstance().lookup(IPFBusiAction.class.getName());
			baService.processAction("APPROVE", "HF", null, reduceVO, context, null);
		} else {
			NCLocator.getInstance().lookup(IplatFormEntry.class).processAction("SAVE","HF",null,reduceVO,context,null);
//			HashMap<String,Object> para = new HashMap<String,Object>();
//			para.put("commitType", "commit");
//			para.put("pageid", "201202520A_card");
//			para.put("dataType", "cardData");
////			para.put("paramInfoMap", "");
//			para.put("OperatorType", "SAVE");
//			
//			nccloud.pub.ampub.vo.PflowInfo pflowInfo = new nccloud.pub.ampub.vo.PflowInfo();
//			pflowInfo.setCommitType((String)para.get("commitType"));
//			pflowInfo.setOperatorType((String)para.get("OperatorType"));
//			pflowInfo.setPageid((String)para.get("pageid"));
//			pflowInfo.setDataType((String)para.get("dataType"));
//			pflowInfo.setLightVO(false);
////			pflowInfo.setParamBodyInfoMap(paramBodyInfoMap);
////			pflowInfo.setParamInfoMap(paramInfoMap);
//			
//			nccloud.framework.web.ui.pattern.billcard.BillCardOperator billCardOperator = new nccloud.framework.web.ui.pattern.billcard.BillCardOperator();
//			billCardOperator.setExcuteFormula(true);
//			billCardOperator.setTransFlag(true);
//			
//			pflowInfo.setProcess(billCardOperator);
////			pflowInfo.setUserMap(userMap);
////			pflowInfo.setOperatorType("START");
//			
//			((IAppScript4Cloud)ServiceLocator.find(IAppScript4Cloud.class)).procFlow(sReduceVO, para, pflowInfo);
			
//			NCLocator.getInstance().lookup(IReduce.class).commit(context, sReduceVO[0]);
//			NCLocator.getInstance().lookup(IReduce4Cloud.class).commit(context, sReduceVO[0]);
//			nccloud.pub.ampub.vo.PflowInfo pflowInfo = new nccloud.pub.ampub.vo.PflowInfo();
//			pflowInfo.setOperatorType("START");
//			
//			((IAppScript4Cloud)ServiceLocator.find(IAppScript4Cloud.class)).procFlow(sReduceVO, new Object(), pflowInfo);
//			
//			NCLocator.getInstance().lookup(ICloudScriptPFlowService.class).exeScriptPFlow(context);
		}
		
//		reduce.commit(null, reduceVO);
		
		
		
//		NCLocator.getInstance().lookup(IplatFormEntry.class).processAction("SAVE","HF",null,reduceVO,null,null);
		
//		boolean spFlag = nccloud.pubimpl.riart.pflow.CloudPfUtil.hasApproveflowDef("HF-01", reduceVO);
//		//没有配置审批流
//		if (!spFlag) {
//			//自动审批
//			NCLocator.getInstance().lookup(IplatFormEntry.class).processAction("APPROVE","HF",null,reduceVO,"ARC",null);
//		}
		// 保存
//		NCLocator.getInstance().lookup(IplatFormEntry.class).processAction("SAVE","HF",null,reduceVO,null,null);
//		NCLocator.getInstance().lookup(IAlter.class).insert(null, aggvoAlter, showAlterKeyList);
		// 提交
//		aggvoAlter = (AlterVO) NCLocator.getInstance().lookup(IplatFormEntry.class).processAction("SAVE", "HG", null,aggvoAlter, null, null);
		
		
//		NCLocator.getInstance().lookup(IPFBusiAction.class).processAction("SAVE", "HF", null, reduceVO, null, null);

	}

	/**
	 * 获取json串
	 * @param request
	 * @return
	 */
	public String requestJson(HttpServletRequest request) {
		StringBuilder sb = new StringBuilder();
		try {
			request.setCharacterEncoding("utf-8");
			BufferedReader reader = request.getReader();
			char[] buff = new char[1024];
			int len;
			while ((len = reader.read(buff)) != -1) {
				sb.append(buff, 0, len);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return sb.toString();
	}

	/**
	 * 响应json串
	 * @param response
	 * @param returnJson
	 * @throws IOException
	 */
	public void responseWriter(HttpServletResponse response, String returnJson) throws IOException {
		response.setCharacterEncoding("UTF-8");
		response.setHeader("Content-type", "application/json; charset=utf-8");
		PrintWriter writer = response.getWriter();
		writer.write(returnJson);
		writer.close();
	}
	
	/**
	 * 获取账簿
	 * @param org
	 * @return
	 * @throws BusinessException
	 */
	private String getAccountingbook(String org) throws BusinessException {
		
		String sql = "SELECT pk_accountingbook FROM org_accountingbook WHERE pk_relorg = ?";
		SQLParameter parameter = new SQLParameter();
		parameter.addParam(org);
		String result = SafeObject.toString(getBaseDAO().executeQuery(sql, parameter, new ColumnProcessor()));
		if (result == null) {
			throw new DAOException("通过pk_org:"+org+"没有找到该该账簿");
		}
		return result;
	}
	
	private BaseDAO getBaseDAO() {
		if (baseDAO == null) {
			baseDAO = new BaseDAO();
		}
		return baseDAO;
	}
	
	/**
	 * 检查唯一来源单据
	 * @param src_id
	 * @throws BusinessException
	 */
	private void selectOnlyID(String src_id) throws BusinessException {
		String sql = "select count(pk_reduce) from fa_reduce where def11 = '"+src_id+"' and dr = 0";
		Integer number = (Integer)getBaseDAO().executeQuery(sql, new ColumnProcessor());
		if(number != 0) {
			 throw new BusinessException("字段 def2 来源单据号已存在");
		}
	}

}
