package nc.bs.ic.m45.ext.rule;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import nc.bs.dao.BaseDAO;
import nc.bs.framework.common.NCLocator;
import nc.bs.ic.m45.sign.rule.AfterRuleForRewritePUSettle;
import nc.bs.logging.Logger;
import nc.impl.pubapp.pattern.rule.IRule;
import nc.itf.pu.m27.ISettleMatch;
import nc.itf.pu.m4201.IStockFinanceQuery;
import nc.itf.uap.IUAPQueryBS;
import nc.jdbc.framework.processor.ArrayListProcessor;
import nc.jdbc.framework.processor.BeanListProcessor;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.vo.ic.general.define.ICBillFlag;
import nc.vo.ic.m45.entity.PurchaseInBodyVO;
import nc.vo.ic.m45.entity.PurchaseInHeadVO;
import nc.vo.ic.m45.entity.PurchaseInVO;
import nc.vo.pu.m27.entity.PurchaseInSettleVO;
import nc.vo.pu.m27.entity.SettleBillVO;
import nc.vo.pu.m27.entity.StockSettleVO;
import nc.vo.pu.m27.enumeration.EnumSettleType;
import nc.vo.pu.m27.pub.SettleEnvironment;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;

public class M45AfterSignRule implements IRule<PurchaseInVO> {

	@Override
	public void process(PurchaseInVO[] vos) {
		if (vos == null || vos[0] == null // 没有选中
				|| null == vos[0].getBodys()// 表体不能为空
				|| null == vos[0].getHead().getFbillflag()// 状态不能为空
				|| 0 != ((Integer) ICBillFlag.SIGN.value()).compareTo(vos[0].getHead().getFbillflag())// 状态不为签字
				|| null == vos[0].getHead().getFreplenishflag() // 采购退库不能为空
				|| !vos[0].getHead().getFreplenishflag().booleanValue()// 采购退库为true
				|| null == vos[0].getBodys()[0].getCsourcetype()// 来源单据类型不能为空
				|| !"21".equals(vos[0].getBodys()[0].getCsourcetype())// 来源单据类型不等于采购订单
		) {
			return;
		}
		if ("XU".equals(vos[0].getHead().getVdef9())) {// xugang
			return;
		}
		String sql = null;
		Object obj = null;
		try {
			if (null == vos[0].getHead().getVdef17()) {
//			sql = radomSettleSQL(vos);
				return;
			} else {
				sql = settleByDef5SQL(vos, vos[0].getHead().getVdef17());
			}
			if (sql == null) {
				return;
			}

			obj = NCLocator.getInstance().lookup(IUAPQueryBS.class).executeQuery(sql, new ColumnProcessor());

			/*
			 * 2017/10/31 pj_叶志安 需求：取消已生成发票时的 报错信息，让其保存。 并实现自动无发票结算操作。
			 */
//			if (obj != null && !this.getParameter().equals("Y")) {
//				throw new Exception("已生成发票" + obj.toString() + "，请删除发票后再进行退货");
//			}

		} catch (BusinessException e) {
			e.printStackTrace();
			ExceptionUtils.wrappBusinessException(e.getMessage());
		} catch (Exception e) {
			ExceptionUtils.wrappBusinessException(e.getMessage());
		}

		if (null == obj) {

			if (null == vos[0].getHead().getVdef17()) {
				radomSettle(vos);
			} else {
				settleByDef5(vos, vos[0].getHead().getVdef17());
			}
		}

	}

	private String getParameter() throws BusinessException {
		BaseDAO dao = new BaseDAO();
		String syncTsValue = BaseToolsFm45.getGlobleSysInitValue("IC122", dao);
		if (syncTsValue == null || syncTsValue.length() == 0) {
			throw new BusinessException("请设置参数\"IC122\"!");
		}
		return syncTsValue;
	}

//			-------------end------yezhian---------------

	private void settleByDef5(PurchaseInVO[] vos, String vdef5) {
		ISettleMatch service_sm = NCLocator.getInstance().lookup(ISettleMatch.class);
		IStockFinanceQuery serv = NCLocator.getInstance().lookup(IStockFinanceQuery.class);// 查询采购财务入
		String cfanaceorgoid = vos[0].getHead().getCfanaceorgoid();
		String pk_org = vos[0].getHead().getPk_org();

		StringBuffer sql = new StringBuffer();
		sql.append(" from po_purchaseinfi po_purchaseinfi inner join po_purchaseinfi_b po_purchaseinfi_b  ");
		sql.append(
				" on po_purchaseinfi_b.pk_stockps = po_purchaseinfi.pk_stockps left join ic_purchasein_h on ic_purchasein_h.vbillcode=po_purchaseinfi.vbillcode where ");
		sql.append(" po_purchaseinfi_b.pk_financeorg = '" + cfanaceorgoid + "' ");
		sql.append(" and po_purchaseinfi.pk_org = '" + pk_org + "' ");
		sql.append(" and po_purchaseinfi.dr = 0 ");
		sql.append(" and po_purchaseinfi_b.dr = 0 ");
		sql.append(" and nvl(naccfeesettlemny, 0) = 0 ");
		sql.append(" and (ftoapflag in (0, 1) ");
		sql.append(" and ftoiaflag in (0, 1)) ");
		sql.append(" and nvl(ninnum, 0) <> 0 ");
		sql.append(" and ic_purchasein_h.cgeneralhid in ('" + vos[0].getHead().getPrimaryKey() + "','"
				+ vos[0].getHead().getVdef17() + "')");
		SettleEnvironment se = new SettleEnvironment(pk_org, EnumSettleType.UI_AUTO);
//	    se.setExecType(MatchExecType.mock);
		Logger.error("\n\n\n~~~~~~~~~~~~~def5~~~~~~~~~~~sql : " + sql + "~~~~~~~~~~~~~~~~~~");
		Logger.debug("\n\n\n~~~~~~~~~~~~~def5~~~~~~~~~~~sql : " + sql + "~~~~~~~~~~~~~~~~~~");

		StockSettleVO[] stocks;
		try {
			stocks = serv.queryPurchaseInByWhereSql(sql.toString());
			Logger.error("\n\n\n~~~~~~~~~~~~~def5~~~~~~~~~~~stocks.length : " + stocks.length + "~~~~~~~~~~~~~~~~~~");
			Logger.debug("\n\n\n~~~~~~~~~~~~~def5~~~~~~~~~~~stocks.length : " + stocks.length + "~~~~~~~~~~~~~~~~~~");
//			for (StockSettleVO stockSettleVO : stocks) {
//				PurchaseInSettleVO bvo = (PurchaseInSettleVO) stockSettleVO;
//				bvo.setNcansettlenum(UFDouble.ZERO_DBL);
//			}
			SettleBillVO[] retvos = service_sm.autoMatch(null, stocks, null, null, se);
//			Logger.error("\n\n\n~~~~~~~~~~~~~def5~~~~~~~~~~~retvos.length : " + retvos.length + "~~~~~~~~~~~~~~~~~~");
//			Logger.debug("\n\n\n~~~~~~~~~~~~~def5~~~~~~~~~~~retvos.length : " + retvos.length + "~~~~~~~~~~~~~~~~~~");
			if (retvos == null)
				throw new Exception("结算失败");
		} catch (BusinessException e) {
			e.printStackTrace();
			ExceptionUtils.wrappBusinessException(e.getMessage());
		} catch (Exception e) {
			ExceptionUtils.wrappBusinessException(e.getMessage());
		}
	}

//将入库单vo转换成 采购财务入 vo
	private StockSettleVO[] getStockSettleVO() {
		return null;

	}

	private void radomSettle(PurchaseInVO[] vos) {
		Set<String> set_pk_order = new HashSet<String>();

		for (PurchaseInBodyVO bodyvo : vos[0].getBodys()) {
			if (null != bodyvo.getCsourcebillhid()) {
				set_pk_order.add(bodyvo.getCsourcebillhid());
			}
		}

		String sql_pk_order = "(";
		String pk_org = vos[0].getHead().getPk_org();
		String cfanaceorgoid = vos[0].getHead().getCfanaceorgoid();

		for (int i = 0; i < set_pk_order.size(); i++) {
			if (i == set_pk_order.size() - 1) {
				sql_pk_order += " pk_order='" + set_pk_order.toArray()[i] + "' ) ";
			} else {
				sql_pk_order += " pk_order='" + set_pk_order.toArray()[i] + "' or ";
			}
		}

		ISettleMatch service_sm = NCLocator.getInstance().lookup(ISettleMatch.class);
		IStockFinanceQuery serv = NCLocator.getInstance().lookup(IStockFinanceQuery.class);// 查询采购财务入

		StringBuffer sql = new StringBuffer();
		sql.append(" from po_purchaseinfi po_purchaseinfi inner join po_purchaseinfi_b po_purchaseinfi_b ");
		sql.append(" on po_purchaseinfi_b.pk_stockps = po_purchaseinfi.pk_stockps where ");
		sql.append(" po_purchaseinfi_b.pk_financeorg = '" + cfanaceorgoid + "' ");
		sql.append(" and po_purchaseinfi.pk_org = '" + pk_org + "' ");
		sql.append(" and po_purchaseinfi.dr = 0 ");
		sql.append(" and po_purchaseinfi_b.dr = 0 ");
		sql.append(" and nvl(naccfeesettlemny, 0) = 0 ");
		sql.append(" and (ftoapflag in (0, 1) ");
		sql.append(" and ftoiaflag in (0, 1)) ");
		sql.append(" and nvl(ninnum, 0) <> 0 ");
		sql.append(" and " + sql_pk_order + " ");

		SettleEnvironment se = new SettleEnvironment(pk_org, EnumSettleType.UI_AUTO);
//	    se.setExecType(MatchExecType.mock);

		Logger.error("\n\n\n~~~~~~~~~~~~~~~~~~~~~~~~sql : " + sql + "~~~~~~~~~~~~~~~~~~");
		Logger.debug("\n\n\n~~~~~~~~~~~~~~~~~~~~~~~~sql : " + sql + "~~~~~~~~~~~~~~~~~~");

		StockSettleVO[] stocks;
		try {
			stocks = serv.queryPurchaseInByWhereSql(sql.toString());

			Logger.error("\n\n\n~~~~~~~~~~~~~~~~~~~~~~~~stocks.length one : " + stocks.length + "~~~~~~~~~~~~~~~~~~");
			Logger.debug("\n\n\n~~~~~~~~~~~~~~~~~~~~~~~~stocks.length one : " + stocks.length + "~~~~~~~~~~~~~~~~~~");

			if (stocks != null) {

				String sql_invo = "select pk_org, vsourcecode as vbillcode from po_invoice_b where dr=0 and "
						+ sql_pk_order + " ";
				List oradata = (List<StockSettleVO>) NCLocator.getInstance().lookup(IUAPQueryBS.class)
						.executeQuery(sql_invo, new ArrayListProcessor());
				List<StockSettleVO> data = null;
				if (oradata != null) {
					data = new ArrayList<StockSettleVO>();
					Object[] obj = null;
					boolean flag = true;
					for (int i = 0; i < stocks.length; i++) {
						flag = true;
						for (int j = 0; j < oradata.size(); j++) {
							obj = (Object[]) oradata.get(j);
							if (stocks[i].getPk_org().equals(obj[0]) && stocks[i].getVbillcode().equals(obj[1])) {
								flag = false;
								break;
							}
						}
						if (flag) {
							data.add(stocks[i]);
						}
					}
				}

				if (data != null) {
					stocks = data.toArray(new StockSettleVO[data.size()]);
				}
				Logger.error(
						"\n\n\n~~~~~~~~~~~~~~~~~~~~~~~~stocks.length two: " + stocks.length + "~~~~~~~~~~~~~~~~~~");
				Logger.debug(
						"\n\n\n~~~~~~~~~~~~~~~~~~~~~~~~stocks.length two: " + stocks.length + "~~~~~~~~~~~~~~~~~~");

				Logger.error("\n\n\n~~~~~~~~~~~~~~~~~~~~~~~~for(stocks.length) start: ~~~~~~~~~~~~~~~~~~");
				Logger.debug("\n\n\n~~~~~~~~~~~~~~~~~~~~~~~~for(stocks.length) start: ~~~~~~~~~~~~~~~~~~");
				for (int i = 0; i < stocks.length; i++) {
					for (int j = 0; j < stocks.length; j++) {
						Logger.error("~~~stocks[i].getPk_order_b()=" + stocks[i].getPk_order_b() + "~~~~");
						Logger.debug("~~~stocks[i].getPk_order_b()=" + stocks[i].getPk_order_b() + "~~~~");
						Logger.error("~~~stocks[i].getPk_stockps_b()=" + stocks[i].getPk_stockps_b() + "~~~~");
						Logger.debug("~~~stocks[i].getPk_stockps_b()=" + stocks[i].getPk_stockps_b() + "~~~~");
						Logger.error("~~~条件=" + (stocks[i].getPk_order_b().equals(stocks[j].getPk_order_b())
								&& !stocks[i].getPk_stockps_b().equals(stocks[j].getPk_stockps_b())) + "~~~~");
						Logger.debug("~~~条件=" + (stocks[i].getPk_order_b().equals(stocks[j].getPk_order_b())
								&& !stocks[i].getPk_stockps_b().equals(stocks[j].getPk_stockps_b())) + "~~~~");

						if (stocks[i].getPk_order_b().equals(stocks[j].getPk_order_b())
								&& !stocks[i].getPk_stockps_b().equals(stocks[j].getPk_stockps_b())) {
							if (stocks[i].getNestprice().doubleValue() != stocks[j].getNestprice().doubleValue()) {
								throw new Exception("订单价格已经修改，请指定对冲入库单据");
							}
						}
					}
				}

				Logger.error("\n\n\n~~~~~~~~~~~~~~~~~~~~~~~~for(stocks.length) end: ~~~~~~~~~~~~~~~~~~");
				Logger.debug("\n\n\n~~~~~~~~~~~~~~~~~~~~~~~~for(stocks.length) end: ~~~~~~~~~~~~~~~~~~");

			}

			SettleBillVO[] retvos = service_sm.autoMatch(null, stocks, null, null, se);

//			Logger.error("\n\n\n~~~~~~~~~~~~~~~~~~~~~~~~retvos.length : " + retvos.length + "~~~~~~~~~~~~~~~~~~");
//			Logger.debug("\n\n\n~~~~~~~~~~~~~~~~~~~~~~~~retvos.length : " + retvos.length + "~~~~~~~~~~~~~~~~~~");

			if (retvos == null)
				throw new Exception("结算失败，请检查是否满足采购结算的规则!");

		} catch (BusinessException e) {
			e.printStackTrace();
			ExceptionUtils.wrappBusinessException(e.getMessage());
		} catch (Exception e) {
			ExceptionUtils.wrappBusinessException(e.getMessage());
		}
	}

	private String settleByDef5SQL(PurchaseInVO[] vos, String vdef5) {
		String sql = "select po_invoice.vbillcode from po_invoice left join po_invoice_b on po_invoice.pk_invoice=po_invoice_b.pk_invoice where po_invoice_b.csourceid='"
				+ vdef5 + "' and po_invoice.dr=0 and po_invoice_b.dr=0";
		return sql;
	}

	private String radomSettleSQL(PurchaseInVO[] vos) throws Exception {
		String resultsql = null;

		Set<String> set_pk_order = new HashSet<String>();

		for (PurchaseInBodyVO bodyvo : vos[0].getBodys()) {
			if (null != bodyvo.getCsourcebillhid()) {
				set_pk_order.add(bodyvo.getCsourcebillhid());
			}
		}

		String sql_pk_order = "(";
		String pk_org = vos[0].getHead().getPk_org();
		String cfanaceorgoid = vos[0].getHead().getCfanaceorgoid();

		for (int i = 0; i < set_pk_order.size(); i++) {
			if (i == set_pk_order.size() - 1) {
				sql_pk_order += " pk_order='" + set_pk_order.toArray()[i] + "' ) ";
			} else {
				sql_pk_order += " pk_order='" + set_pk_order.toArray()[i] + "' or ";
			}
		}

		IStockFinanceQuery serv = NCLocator.getInstance().lookup(IStockFinanceQuery.class);// 查询采购财务入

		StringBuffer sql = new StringBuffer();
		sql.append(" from po_purchaseinfi po_purchaseinfi inner join po_purchaseinfi_b po_purchaseinfi_b ");
		sql.append(" on po_purchaseinfi_b.pk_stockps = po_purchaseinfi.pk_stockps where ");
		sql.append(" po_purchaseinfi_b.pk_financeorg = '" + cfanaceorgoid + "' ");
		sql.append(" and po_purchaseinfi.pk_org = '" + pk_org + "' ");
		sql.append(" and po_purchaseinfi.dr = 0 ");
		sql.append(" and po_purchaseinfi_b.dr = 0 ");
		sql.append(" and nvl(naccfeesettlemny, 0) = 0 ");
		sql.append(" and (ftoapflag in (0, 1) ");
		sql.append(" and ftoiaflag in (0, 1)) ");
		sql.append(" and nvl(ninnum, 0) <> 0 ");
		sql.append(" and " + sql_pk_order + " ");

		StockSettleVO[] stocks;
		stocks = serv.queryPurchaseInByWhereSql(sql.toString());

		if (stocks == null || stocks.length == 0) {
			return resultsql;
		}

		String sql_billcode = "(";
		for (int i = 0; i < stocks.length; i++) {
			if (i == stocks.length - 1) {
				sql_billcode += " vbillcode='" + stocks[i].getVbillcode() + "') ";
			} else {
				sql_billcode += " vbillcode='" + stocks[i].getVbillcode() + "' or ";
			}
		}

		String ss = "select * from ic_purchasein_h where dr=0 and cgeneralhid not in(select csourceid from po_invoice_b where dr=0) and pk_org='"
				+ pk_org + "' and cfanaceorgoid='" + cfanaceorgoid + "' and dr=0 and " + sql_billcode + " ";

		List<PurchaseInHeadVO> headvos = (List<PurchaseInHeadVO>) NCLocator.getInstance().lookup(IUAPQueryBS.class)
				.executeQuery(ss, new BeanListProcessor(PurchaseInHeadVO.class));
		if (headvos == null || headvos.size() == 0)
			throw new Exception("已生成发票，请删除发票后再进行退货");

		List<String> list = new ArrayList<String>();

		for (int i = 0; i < headvos.size(); i++) {
			if (headvos.get(i).getFreplenishflag() == null || !headvos.get(i).getFreplenishflag().booleanValue()) {
				list.add(headvos.get(i).getPrimaryKey());
			}
		}

		String sql_kc = "(";
		for (int i = 0; i < list.size(); i++) {
			if (i == list.size() - 1) {
				sql_kc += " po_invoice_b.csourceid='" + list.get(i) + "') ";
			} else {
				sql_kc += " po_invoice_b.csourceid='" + list.get(i) + "' or ";
			}
		}

		resultsql = "select po_invoice.vbillcode from po_invoice left join po_invoice_b on po_invoice.pk_invoice=po_invoice_b.pk_invoice where po_invoice.dr=0 and po_invoice_b.dr=0 and "
				+ sql_kc + " ";
		return resultsql;
	}

}
