package nc.bs.arap.termendtransact;

/**
 * 月末处理BO类。
 * 创建日期：(2001-8-21 10:06:57)
 * 最后修改日期：(2001-8-21 10:06:57)
 * @author：wyan
 */

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import nc.bs.bd.businessevent.ReportInfo;
import nc.bs.framework.common.InvocationInfoProxy;
import nc.bs.framework.common.NCLocator;
import nc.itf.arap.termendtransact.ICloseAccountService;
import nc.itf.fi.pub.SysInit;
import nc.itf.uap.sf.ICreateCorpQueryService;
import nc.pubitf.accperiod.AccountCalendar;
import nc.pubitf.fip.service.IFipQueryService;
import nc.pubitf.org.IAccountingBookPubService;
import nc.pubitf.org.ICloseAccPubServicer;
import nc.pubitf.org.ICloseAccQryPubServicer;
import nc.vo.arap.dap.RetBillVo;
import nc.vo.arap.pub.ArapConstant;
import nc.vo.arap.termendtransact.AgiotageVO;
import nc.vo.arap.termendtransact.FilterCondVO;
import nc.vo.arap.termendtransact.RemoteTransferVO;
import nc.vo.arap.termendtransact.ReportVO;
import nc.vo.arap.termendtransact.TermEndVO;
import nc.vo.arap.transaction.FirstNotClosedAccountMonthVO;
import nc.vo.arap.utils.ARAPModuleEnableUtil;
import nc.vo.bd.period2.AccperiodmonthVO;
import nc.vo.fipub.exception.ExceptionHandler;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFBoolean;

public class ReckoningBO { 
	private static final String AP22 = "AP22";
	private static final String AR22 = "AR22";
	private List<ReportInfo> reportInfo = new ArrayList<ReportInfo>();

	/**
	 * ReckoningBO 构造子注解。
	 */
	public ReckoningBO() {
		super();
	}

	/**
	 * 从会计平台获得截止到本月没有生成会计凭证的单据信息。 创建日期：(2002-6-6 14:38:55)
	 * @return java.util.Vector
	 * @param vo nc.vo.arap.termendtransact.FilterCondVO
	 */
	private RetBillVo[] getNotCreateVoucherDoc(FilterCondVO vo) throws BusinessException {

		RetBillVo[] voNoCreateVouDocs = null;
		try {
			String year = vo.getYear();
			String month = vo.getQj();

			AccountCalendar ac = AccountCalendar.getInstanceByPk_org(vo.getPk_org());
			ac.set(year, month);

			String[] billPks = NCLocator
					.getInstance()
					.lookup(IFipQueryService.class)
					.queryOperatingBill(ArapConstant.ARAP_AR_BILLCLASS.equals(vo.getSfbz()) ? "AR" : "AP", null, vo.getPk_org(), ac.getMonthVO().getBegindate(), ac.getMonthVO().getEnddate(),
							UFBoolean.FALSE);
			if (billPks == null || billPks.length == 0) {
				return null;
			}
			ReckoningDMO dmo = new ReckoningDMO();
			voNoCreateVouDocs = dmo.getRetBillVOByPks(billPks, vo);

		} catch (Exception e) {
			throw ExceptionHandler.handleException(this.getClass(), e);
		}

		return voNoCreateVouDocs;
	}

	/**
	 * 主要功能： 主要算法： 异常描述： 创建日期：(2001-9-21 15:51:09) 最后修改日期：(2001-9-21 15:51:09)
	 * @author：wyan
	 * @return java.util.Vector
	 * @param vRep nc.vo.arap.termendtransact.ReportVO
	 */
	public Vector<Object> getRowTitle(ReportVO vRep) throws BusinessException {

		Vector<Object> vData = new Vector<Object>();
		try {
			vData.add(Integer.valueOf(vRep.getBh()));
			vData.add(vRep.getInfo());
			vData.add(vRep.getCount());
		} catch (Exception e) {
			throw ExceptionHandler.handleException(this.getClass(), e);
		}
		return vData;
	}

	/**
	 * 主要功能：月末检查 主要算法： 异常描述： 创建日期：(2001-8-16 17:58:10) 最后修改日期：(2001-8-16 17:58:10)
	 * @author：wyan
	 */
	public RemoteTransferVO onReckoningCheck(FilterCondVO voCond, AgiotageVO voCurrency) throws BusinessException {

		RemoteTransferVO voRemote = new RemoteTransferVO();
		ReportVO repVO = new ReportVO();
		Vector<Vector<String>> vCheckData = new Vector<Vector<String>>();
		Vector<Vector<String>> vResult = new Vector<Vector<String>>();
		boolean bState = true; /* 结账标志：true-表示可以结账 false-标志不可以结账 */
		try {
			ReckoningDMO dmo = new ReckoningDMO();
			int i = 1; /* 因为用户可能选择几项检查，所以序号为动态 */
			/* 本月单据是否全部生效 */
			if (voCond.getMode1() != null) {
				vCheckData = dmo.onReckoningCheckStep1(voCond);
				vResult = vCheckData;
				i++;
				if ((voCond.getMode1().equals("control")) && (vCheckData.size() > 1)) /* 减去标题行 */{
					bState = false;
				}

			}
			/* 本月收付款单是否全部核销 */
			if (voCond.getMode2() != null) {
				vCheckData = dmo.onReckoningCheckStep2(voCond);
				Vector<String> vTem = new Vector<String>();
				vTem.addElement(Integer.valueOf(i).toString());
				if (voCond.getSfbz().equals(ArapConstant.ARAP_AR_BILLCLASS)) {
					vTem.addElement(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("2006v61020_0", "02006v61020-0048")/*
																															 * @res "本月未核销的收款单"
																															 */);
				}
				if (voCond.getSfbz().equals(ArapConstant.ARAP_AP_BILLCLASS)) {
					vTem.addElement(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("2006v61020_0", "02006v61020-0049")/*
																															 * @res "本月未核销的付款单"
																															 */);
				}
				vTem.addElement(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("2006v61020_0", "02006v61020-0052", null, new String[] { String.valueOf(vCheckData.size()) }));// 共{0}张

				vResult.addElement(vTem);
				if (vCheckData.size() != 0) {
					for (int j = 0; j < vCheckData.size(); j++) {
						vResult.addElement(vCheckData.elementAt(j));
					}
				}
				i++;
				if ((voCond.getMode2().equals("control")) && (vCheckData.size() != 0)) {
					bState = false;
				}
			}
			/* 本月单据是否全部生成会计凭证 */
			if (voCond.getMode3() != null) {
				Vector<String> vTem = new Vector<String>();
				int iSum = 0;
				RetBillVo[] voNotCreateVouDocs = getNotCreateVoucherDoc(voCond);
				if (voNotCreateVouDocs == null) {
					voNotCreateVouDocs = new RetBillVo[0];
				}
				vTem.addElement(Integer.valueOf(i).toString());
				vTem.addElement(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("2006v61020_0", "02006v61020-0051")/*
																														 * @res "本月未生成会计凭证单据"
																														 */);
				vTem.addElement(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("common", "UC000-0002282")/*
																												 * @res "数量"
																												 */);
				vResult.addElement(vTem);
				if (voNotCreateVouDocs.length != 0) {
					for (int j = 0; j < voNotCreateVouDocs.length; j++) {
						Vector<String> v = new Vector<String>();
						v.addElement("");
						v.addElement(voNotCreateVouDocs[j].getBillType() + voNotCreateVouDocs[j].getBillNo());
						v.addElement("");
						vResult.addElement(v);
					}
				}
				vResult.elementAt(vResult.size() - iSum - 1).setElementAt(
						nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("2006v61020_0", "02006v61020-0052", null, new String[] { String.valueOf(voNotCreateVouDocs.length) }), 2);// 共{0}张
				i++;
				if ((voCond.getMode3().equals("control")) && (voNotCreateVouDocs.length != 0)) {
					bState = false;
				}
			}
			/* 本月单据是否全部计算过汇兑损益 */
			if (voCond.getMode4() != null) {
				repVO = dmo.onReckoningCheckStep3(voCond, voCurrency);
				Vector<String> vTem = new Vector<String>();
				vTem.addElement(Integer.valueOf(i).toString());
				vTem.addElement(repVO.getInfo());
				vTem.addElement("");
				vResult.addElement(vTem);
				if ((voCond.getMode4().equals("control")) && (!repVO.getState())) {
					bState = false;
				}
			}
			// getDJZB().remove();
			voRemote.setTranData1(vResult); /* 结账检查数据 */
			voRemote.setReckoningState(bState); /* 结账 */

		} catch (Exception e) {
			throw ExceptionHandler.handleException(this.getClass(), e);
		}

		return voRemote;

	}

	public static String[] getPreviousSettleAccountYearMonth(String[] enableInfo, String[] cancelSettInfo, String prodID, String pk_org) throws BusinessException {
		FirstNotClosedAccountMonthVO firstNoAccVO = new FirstNotClosedAccountMonthVO();
		String accYear = null;
		String accMonth = null;

		try {
			String year = cancelSettInfo[0]; /* 选中的要取消结账的月所在地年度 */
			String cope = cancelSettInfo[1]; /* 选中的要取消结账的月所在地期间 */

			AccountCalendar ac = AccountCalendar.getInstanceByPk_org(pk_org);
			ac.set(year);
			if (enableInfo == null) {
				enableInfo = NCLocator.getInstance().lookup(ICreateCorpQueryService.class).queryEnabledPeriod(pk_org, prodID);
			}

			String enabledYear = enableInfo[0]; /* 启用年 */
			String enabledMonth = enableInfo[1]; /* 启用月 */

			if (year.equals(enabledYear) && (cope.equals(enabledMonth))) {
				return new String[2];
			}
			if (cope.equals("01")) {
				accYear = Integer.valueOf(Integer.valueOf(year).intValue() - 1).toString();
				ac.set(accYear);
				AccperiodmonthVO[] tmpMonths = ac.getMonthVOsOfCurrentYear();
				accMonth = tmpMonths[tmpMonths.length - 1].getYearmth().substring(5, 7);
			}
			if (!cope.equals("01")) {
				accYear = year;
				Integer iMon = Integer.valueOf(Integer.valueOf(cope).intValue() - 1);
				if (iMon.intValue() < 10) {
					accMonth = "0" + iMon.toString();
				} else {
					accMonth = iMon.toString();
				}
			}
			firstNoAccVO.setNotAccMonth(accMonth);
			firstNoAccVO.setNotAccYear(accYear);
		} catch (Exception ex) {
			ExceptionHandler.handleException(ex);
		}

		return new String[] { accYear, accMonth };
	}

	/**
	 * 月末处理后台操作
	 * @param prodId 系统编码
	 * @param endVO 处理VO
	 * @param isCancel 是否反向操作
	 * @throws BusinessException
	 */
	public void termEndOperation(String prodId, TermEndVO endvo, boolean isCancel) throws BusinessException {
		boolean enabled = ARAPModuleEnableUtil.isEnable(InvocationInfoProxy.getInstance().getGroupId(), ARAPModuleEnableUtil.GL_MODULE_ID); // 总账模块是否启用，没有启用不校验
		if (enabled) {
			checkUnCloseAcc(prodId.equals("AR"), endvo.getYear(), endvo.getMonth(), endvo.getPk_org());
		}
		if (isCancel) {
			String[] previousSettleAccountYearMonth = getPreviousSettleAccountYearMonth(new String[] { endvo.getEnableyear(), endvo.getEnablemonth() },
					new String[] { endvo.getYear(), endvo.getMonth() }, prodId, endvo.getPk_org());
			endvo.setYear(previousSettleAccountYearMonth[0]);
			endvo.setMonth(previousSettleAccountYearMonth[1]);
		}

		try {
			NCLocator.getInstance().lookup(ICloseAccountService.class).updateCloseAccountInfo(endvo.getNodecode(), endvo.getPk_org(), endvo.getYear(), endvo.getMonth());
		} catch (Exception e) {
			ExceptionHandler.handleException(e);
		}
		// 取消结账后，需要将结账信息传入uap的关帐模块
		NCLocator.getInstance().lookup(ICloseAccPubServicer.class).reAccount(endvo.getNodecode(), endvo.getPk_org(), endvo.getPk_org(), endvo.getPk_periodmonth());
	}

	public List<ReportInfo> onReckoningReportCheck(FilterCondVO voCond, AgiotageVO voCurrency) throws BusinessException {
		ReportVO repVO = new ReportVO();
		Vector<Vector<String>> vCheckData = new Vector<Vector<String>>();
		Vector<Vector<String>> vResult = new Vector<Vector<String>>();
		UFBoolean bState = UFBoolean.TRUE; /* 结账标志：true-表示可以结账 false-标志不可以结账 */
		String periodState = voCond.getPeriodState();
		try {
			ReckoningDMO dmo = new ReckoningDMO();
			int i = 1; /* 因为用户可能选择几项检查，所以序号为动态 */
			/* 本月单据是否全部生效 */
			if (voCond.getMode1() != null) {
				UFBoolean isStrongCheck = UFBoolean.FALSE;
				vCheckData = dmo.onReckoningCheckStep1(voCond);
				vResult = vCheckData;
				i++;
				List<Vector<String>> detail = Collections.list(vCheckData.elements());
				List<String> msg = new ArrayList<>();
				for (int j = 1; j < detail.size(); j++) {
					Vector<String> vector = detail.get(j);
					if (vector.elementAt(1) == null) {
						continue;
					}
					msg.add(vector.elementAt(1));
				}
				if (("control".equals(voCond.getMode1())) && (vCheckData.size() > 1)) /* 减去标题行 */{
					bState = UFBoolean.FALSE;
				}
				if ("control".equals(voCond.getMode1())) {
					isStrongCheck = UFBoolean.TRUE;
				}
				addReprotInfo(vResult.get(0).get(1), bState, isStrongCheck, vResult.get(0).get(2), periodState, msg);// 没单据号的是协同未确认的

			}
			/* 本月收付款单是否全部核销 */
			if (voCond.getMode2() != null) {
				UFBoolean isStrongCheck = UFBoolean.FALSE;
				vCheckData = dmo.onReckoningCheckStep2(voCond);
				Vector<String> vTem = new Vector<String>();
				vTem.addElement(Integer.valueOf(i).toString());
				if (ArapConstant.ARAP_AR_BILLCLASS.equals(voCond.getSfbz())) {
					vTem.addElement(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("2006v61020_0", "02006v61020-0048")/*
																															 * @res "本月未核销的收款单"
																															 */);
				}
				if (ArapConstant.ARAP_AP_BILLCLASS.equals(voCond.getSfbz())) {
					vTem.addElement(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("2006v61020_0", "02006v61020-0049")/*
																															 * @res "本月未核销的付款单"
																															 */);
				}
				vTem.addElement(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("2006v61020_0", "02006v61020-0052", null, new String[] { String.valueOf(vCheckData.size()) }));// 共{0}张
				if (("control".equals(voCond.getMode2())) && (vCheckData.size() != 0)) {
					bState = UFBoolean.FALSE;
				}
				if ("control".equals(voCond.getMode2())) {
					isStrongCheck = UFBoolean.TRUE;
				}
				vResult.addElement(vTem);
				if (vCheckData.size() != 0) {

					List<Vector<String>> detail = Collections.list(vCheckData.elements());
					List<String> msg = new ArrayList<>();
					for (int j = 0; j < detail.size(); j++) {
						Vector<String> vector = detail.get(j);
						msg.add(vector.elementAt(1));
					}
					addReprotInfo(vTem.elementAt(1), bState, isStrongCheck, vTem.elementAt(2), periodState, msg);
				}
				i++;

			}
			/* 本月单据是否全部生成会计凭证 */
			if (voCond.getMode3() != null) {
				UFBoolean isStrongCheck = UFBoolean.FALSE;
				Vector<String> vTem = new Vector<String>();
				int iSum = 0;
				RetBillVo[] voNotCreateVouDocs = getNotCreateVoucherDoc(voCond);
				if (voNotCreateVouDocs == null) {
					voNotCreateVouDocs = new RetBillVo[0];
				}
				vTem.addElement(Integer.valueOf(i).toString());
				vTem.addElement(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("2006v61020_0", "02006v61020-0051")/*
																														 * @res "本月未生成会计凭证单据"
																														 */);
				vTem.addElement(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("common", "UC000-0002282")/*
																												 * @res "数量"
																												 */);
				vResult.addElement(vTem);

				List<String> detail = new ArrayList<>();// 结账报告详细信息

				if (voNotCreateVouDocs.length != 0) {

					for (int j = 0; j < voNotCreateVouDocs.length; j++) {
						Vector<String> v = new Vector<String>();
						v.addElement("");
						v.addElement(voNotCreateVouDocs[j].getBillType() + voNotCreateVouDocs[j].getBillNo());
						v.addElement("");
						detail.add(v.elementAt(1));
						// vResult.addElement(v);
					}
				}
				vResult.elementAt(vResult.size() - iSum - 1).setElementAt(
						nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("2006v61020_0", "02006v61020-0052", null, new String[] { String.valueOf(voNotCreateVouDocs.length) }), 2);// 共{0}张
				i++;
				if ((voCond.getMode3().equals("control")) && (voNotCreateVouDocs.length != 0)) {
					bState = UFBoolean.FALSE;
				}
				if ("control".equals(voCond.getMode3())) {
					isStrongCheck = UFBoolean.TRUE;
				}
				addReprotInfo(vTem.elementAt(1), bState, isStrongCheck, vTem.elementAt(2), periodState, detail);
			}
			/* 本月单据是否全部计算过汇兑损益 */
			if (voCond.getMode4() != null) {
				UFBoolean isStrongCheck = UFBoolean.FALSE;
				repVO = dmo.onReckoningCheckStep3(voCond, voCurrency);
				Vector<String> vTem = new Vector<String>();
				vTem.addElement(Integer.valueOf(i).toString());
				vTem.addElement(repVO.getInfo());
				vTem.addElement("");
				vResult.addElement(vTem);
				if ((voCond.getMode4().equals("control")) && (!repVO.getState())) {
					bState = UFBoolean.FALSE;
				}
				if ("control".equals(voCond.getMode4())) {
					isStrongCheck = UFBoolean.TRUE;
				}
				addReprotInfo(repVO.getInfo(), bState, isStrongCheck, null, periodState, null);// 此提示不准确提示数据的个数
			}

		} catch (Exception e) {
			throw ExceptionHandler.handleException(this.getClass(), e);
		}

		return reportInfo;

	}

	/**
	 * reportInfo信息封装
	 * @param checkitem 检查项
	 * @param isPass 是否通过
	 * @param isStrongCheck 是否系统强校验
	 * @param explain 说明（几张之类的）
	 */
	private void addReprotInfo(String checkitem, UFBoolean isPass, UFBoolean isStrongCheck, String explain, String periodState, List<String> detail) {
		ReportInfo info = new ReportInfo();
		info.setPk_accperiod(periodState);
		info.setIsPass(isPass);
		info.setIsStrongCheck(isStrongCheck);
		info.setCheckItem(checkitem);
		info.setExplain(explain);
		if (detail != null) {
			info.setDetail(detail);
		}
		reportInfo.add(info);
	}

	private void checkUnCloseAcc(boolean isar2, String year, String cope, String pk_org) throws BusinessException {
		Map<String, String> book = NCLocator.getInstance().lookup(IAccountingBookPubService.class).queryAccountingBookIDByFinanceOrgIDWithMainAccountBook(new String[] { pk_org });
		String pkbook = null;
		if (book == null || book.size() == 0) {
			return;
		}

		String param = SysInit.getParaString(pk_org, isar2 ? AR22 : AP22);

		if ("Y".equals(param)) {
			pkbook = book.values().iterator().next();
			String period = year + "-" + cope;

			boolean res = NCLocator.getInstance().lookup(ICloseAccQryPubServicer.class).isCloseByAccountBookId(pkbook, period);

			String para = SysInit.getParaString(pk_org, "GL034");
			if (res && para != null && para.equals(pkbook)) {
				throw new BusinessException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("2006pub_0", "02006pub-0475")/* @res "总账已经关帐，不能进行应收应付反结账！" */);
			}
		}

	}
}