package nc.impl.fa.asset;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import nc.bs.am.framework.action.IActionTemplate;
import nc.bs.am.framework.action.IRule;
import nc.bs.am.framework.action.update.UpdateActionTemplate;
import nc.bs.dao.DAOException;
import nc.bs.framework.common.InvocationInfoProxy;
import nc.bs.logging.Logger;
import nc.bs.uif2.validation.IValidationService;
import nc.bs.uif2.validation.ValidationException;
import nc.bs.uif2.validation.ValidationFrameworkUtil;
import nc.bs.uif2.validation.Validator;
import nc.impl.am.bill.BillBaseDAO;
import nc.impl.am.bill.rule.AddAuditInfoBeforeRule;
import nc.impl.am.bill.rule.SetBizScopeInfoBeforeRule;
import nc.impl.am.bill.rule.VOSagasStatusCheckBeforeRule;
import nc.impl.am.bill.rule.VoStatusSetBeforeRule;
import nc.impl.am.common.InSqlManager;
import nc.impl.am.db.DBAccessUtil;
import nc.impl.am.db.QueryUtil;
import nc.impl.am.db.processor.ColumnSetProcessor;
import nc.impl.am.db.processor.CountProcessor;
import nc.impl.am.db.processor.KeyValueMapProcessor;
import nc.impl.am.plugin.ExtensionPointConst;
import nc.impl.am.plugin.PluginContext;
import nc.impl.am.plugin.PluginServiceImpl;
import nc.impl.am.plugin.PluginTypeConst;
import nc.impl.fa.asset.plugin.AssetAlterTabQuery;
import nc.impl.fa.asset.plugin.AssetDepTabQuery;
import nc.impl.fa.asset.plugin.AssetDeployTabQuery;
import nc.impl.fa.asset.plugin.AssetDevalueTabQuery;
import nc.impl.fa.asset.plugin.AssetEvaluateTabQuery;
import nc.impl.fa.asset.plugin.AssetReduceTabQuery;
import nc.impl.fa.asset.plugin.DefultTabQuery;
import nc.impl.fa.asset.plugin.DeptScaleTabQuery;
import nc.impl.fa.asset.relative.action.RelateEventObject;
import nc.impl.fa.asset.relative.handler.ClientRelateHandler;
import nc.impl.fa.asset.relative.handler.IRelateHandler;
import nc.impl.fa.asset.relative.manager.RelativeActionManager;
import nc.impl.fa.asset.relative.manager.RelativeFactory;
import nc.impl.fa.asset.relative.manager.RelativeTool;
import nc.impl.fa.asset.rule.BackupSynchroDeleteAfterRule;
import nc.impl.fa.asset.rule.BackupSynchroUpdateBeforeRule;
import nc.impl.fa.asset.rule.BeforeCheckDownstream;
import nc.impl.fa.asset.rule.CategoryChangeLogAfterRule;
import nc.impl.fa.asset.rule.CleanNumNullData;
import nc.impl.fa.asset.rule.CodeDeleteRule;
import nc.impl.fa.asset.rule.CodeInsertAfterRule;
import nc.impl.fa.asset.rule.CodeInsertBeforeRule;
import nc.impl.fa.asset.rule.CodeUpdateRule;
import nc.impl.fa.asset.rule.DailyLogUpdateAfterRule;
import nc.impl.fa.asset.rule.DelHistoryDBDataUpdateBeforeRule;
import nc.impl.fa.asset.rule.DepUsedFileValueBeforeRule;
import nc.impl.fa.asset.rule.DeployFlagInsertBeforeRule;
import nc.impl.fa.asset.rule.DeptScaleDeleteBeforeRule;
import nc.impl.fa.asset.rule.DeptScaleInsertAfterRule;
import nc.impl.fa.asset.rule.DeptScaleInsertBeforeRule;
import nc.impl.fa.asset.rule.DeptScaleUpdateBeforeRule;
import nc.impl.fa.asset.rule.LogDeleteAfterRule;
import nc.impl.fa.asset.rule.LogInsertAfterRule;
import nc.impl.fa.asset.rule.LogUpdateAfterRule;
import nc.impl.fa.asset.rule.MultiCurrencySaveBeforeRule;
import nc.impl.fa.asset.rule.PermissionDataChangeRule;
import nc.impl.fa.asset.rule.ProjectTSInsertBeforeRule;
import nc.impl.fa.asset.rule.SagaCtrlAfterRule;
import nc.impl.fa.asset.rule.SendMessageToFipDeleteAfterRule;
import nc.impl.fa.asset.rule.SendMessageToFipInsertAfterRule;
import nc.impl.fa.asset.rule.SendMessageToFipUpdateAfterRule;
import nc.impl.fa.asset.rule.SetHistoryAfterRule;
import nc.impl.fa.asset.rule.SetHistoryDeleteBeforeRule;
import nc.impl.fa.asset.rule.SetHistorySaveBeforeRule;
import nc.impl.fa.asset.rule.SetHistoryUpdateBeforeRule;
import nc.impl.fa.asset.rule.TabCardKeyUpdateBeforeRule;
import nc.impl.fa.asset.rule.UpdateSrcMsg4CardAfterRule;
import nc.impl.fa.asset.rule.ValidatorCheckRule;
import nc.impl.fa.asset.rule.WriteBackBillDeleteAfterRule;
import nc.impl.fa.asset.rule.WriteBackBillInsertAfterRule;
import nc.impl.fa.asset.rule.WriteBackBillUpdateAfterRule;
import nc.impl.fa.asset.tbb.BudgetCtlDeleteBeforeRule;
import nc.impl.fa.asset.tbb.BudgetCtlInsertBeforeRule;
import nc.impl.fa.asset.tbb.BudgetCtlUpdateBeforeRule;
import nc.impl.fa.asset.util.AccbookNextHandleQueryFactory;
import nc.impl.fa.asset.util.AssetScaleProcessUtil;
import nc.impl.fa.asset.util.AssetUseDeptQuery;
import nc.impl.fa.asset.validator.AccbookValidator;
import nc.impl.fa.asset.validator.AppBillValidator;
import nc.impl.fa.asset.validator.CodeValidator;
import nc.impl.fa.asset.validator.DailyDepLisenceValidator;
import nc.impl.fa.asset.validator.DepDateValidator;
import nc.impl.fa.asset.validator.DeptSealValidator;
import nc.impl.fa.asset.validator.ExpenseOutDataValidator;
import nc.impl.fa.asset.validator.MinUnClosedValidator;
import nc.impl.fa.asset.validator.NextHandlerValidator;
import nc.impl.fa.asset.validator.NumericValidator;
import nc.impl.fa.asset.validator.ProfitBillValidator;
import nc.impl.fa.asset.validator.RentOutDataValidator;
import nc.impl.fa.asset.validator.TransAssetBillValidator;
import nc.impl.fa.asset.validator.UsingStatusValidator;
import nc.impl.fa.asset.validator.VoucherAddValidator;
import nc.impl.fa.asset.validator.VoucherDepValidator;
import nc.impl.fa.asset.validator.WorkLoanValidator;
import nc.impl.fa.dep.AssetSimulateDepFactory;
import nc.itf.am.prv.IBillCodeManageService;
import nc.itf.am.pub.ICategoryFaService;
import nc.itf.bd.userdefitem.IUserdefitemQryService;
import nc.itf.fa.prv.IAsset;
import nc.itf.fa.service.ICategoryService;
import nc.itf.fa.service.IQueryAssetTabDataPlugin;
import nc.jdbc.framework.SQLParameter;
import nc.jdbc.framework.processor.ArrayListProcessor;
import nc.jdbc.framework.processor.BaseProcessor;
import nc.jdbc.framework.processor.ResultSetProcessor;
import nc.md.MDBaseQueryFacade;
import nc.md.common.AssociationKind;
import nc.md.model.IBean;
import nc.pub.billcode.itf.IBillcodeManage;
import nc.pub.billcode.vo.BillCodeContext;
import nc.pub.fa.asset.manager.AssetHelperHandleUtil;
import nc.pub.fa.asset.relation.RelativeDataVO;
import nc.pub.fa.card.AssetProcessor;
import nc.pub.fa.card.AssetQuerySqlTool;
import nc.pub.fa.card.AssetStateConst;
import nc.pub.fa.card.AssetTabConstManager;
import nc.pub.fa.card.AssetUseConst;
import nc.pub.fa.card.CardTabConst;
import nc.pub.fa.card.CardVOUtils;
import nc.pub.fa.card.QueryTabDataContext;
import nc.pub.fa.common.consts.BudgetControlConst;
import nc.pub.fa.common.consts.ParaValueConst;
import nc.pub.fa.common.util.AccbookPowerUtil;
import nc.pub.fa.common.util.MDUtils;
import nc.pub.fa.common.util.UseDeptScaleUtils;
import nc.pub.fa.dep.DepResultVO;
import nc.pub.fa.tbb.NtbParamTool;
import nc.pubitf.org.IAccountingBookPubService;
import nc.pubitf.org.IDeptPubService;
import nc.ui.pub.formulaparse.FormulaParse;
import nc.vo.am.common.AMSuperVO;
import nc.vo.am.common.AbstractAggBill;
import nc.vo.am.common.util.ArrayUtils;
import nc.vo.am.common.util.AssertUtils;
import nc.vo.am.common.util.BaseVOUtils;
import nc.vo.am.common.util.CloneUtil;
import nc.vo.am.common.util.CollectionUtils;
import nc.vo.am.common.util.ExceptionUtils;
import nc.vo.am.common.util.MultiLanguageUtil;
import nc.vo.am.common.util.StringUtils;
import nc.vo.am.common.util.UFDoubleUtils;
import nc.vo.am.manager.AccbookManager;
import nc.vo.am.manager.LockManager;
import nc.vo.am.manager.ParameterManager;
import nc.vo.am.proxy.AMProxy;
import nc.vo.bd.userdefrule.UserdefitemVO;
import nc.vo.fa.asset.AggAssetVO;
import nc.vo.fa.asset.AssetEntiretyVO;
import nc.vo.fa.asset.AssetVO;
import nc.vo.fa.assetcard.AggCardVO;
import nc.vo.fa.assetcard.CardVO;
import nc.vo.fa.assetcard.CardhistoryVO;
import nc.vo.fa.category.CategoryVO;
import nc.vo.fa.depmethod.DepmethodVO;
import nc.vo.fa.deptscale.DeptScaleVO;
import nc.vo.fa.linkquery.LinkQueryAssetData;
import nc.vo.ml.NCLangRes4VoTransl;
import nc.vo.org.DeptVO;
import nc.vo.pub.AggregatedValueObject;
import nc.vo.pub.BusinessException;
import nc.vo.pub.CircularlyAccessibleValueObject;
import nc.vo.pub.IAttributeMeta;
import nc.vo.pub.SuperVO;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pub.lang.UFDate;
import nc.vo.pubapp.pattern.pub.Constructor;
import nc.vo.uif2.LoginContext;
import nc.vo.util.AuditInfoUtil;
import nc.vo.util.BDPKLockUtil;
import nc.vo.util.BDVersionValidationUtil;

public class AssetImpl extends BillBaseDAO<AggCardVO> implements IAsset {
  private DBAccessUtil dbUtil = new DBAccessUtil();
  
  public AssetEntiretyVO insertCard(LoginContext context, AssetEntiretyVO entiretyvo) throws BusinessException {
    AggCardVO aggvo = CardVOUtils.changeAssetEntiretyVOTOAggCardVO(entiretyvo);
    Object obj = entiretyvo.getSpecialValue(BudgetControlConst.budgetOtherField);
    if (obj != null && obj instanceof nc.vo.fa.tbb.ControlRule)
      aggvo.getParentVO().setAttributeValue(BudgetControlConst.budgetOtherField, obj); 
    ((IAsset)AMProxy.lookup(IAsset.class)).insertCardVO(aggvo);
    AssetEntiretyVO returnData = CardVOUtils.changeAggCardVOTOAssetEntiretyVO(aggvo);
    return returnData;
  }
  
  public void insertCardVO(AggCardVO aggvo) throws BusinessException {
    insertBillVO(new AggCardVO[] { aggvo });
  }
  
  protected List<Validator> getInsertCheckList() {
    List<Validator> validators = new ArrayList<>();
    validators.add(new DailyDepLisenceValidator());
    validators.add(new MinUnClosedValidator());
    validators.add(new DeptSealValidator());
    validators.add(new UsingStatusValidator());
    validators.add(new NumericValidator());
    validators.add(new AppBillValidator());
    validators.add(new ProfitBillValidator());
    validators.add(new AccbookValidator());
    validators.add(new WorkLoanValidator());
    validators.add(new VoucherDepValidator());
    validators.add(new DepDateValidator());
    validators.add(new TransAssetBillValidator());
    return validators;
  }
  
  protected void initInsertActionRules(IActionTemplate<AggCardVO> insertAction) {
    insertAction.addBeforeRule((IRule)new VoStatusSetBeforeRule(2));
    insertAction.addBeforeRule((IRule)new AddAuditInfoBeforeRule());
    insertAction.addBeforeRule((IRule)new SetBizScopeInfoBeforeRule());
    List<Validator> validators = getInsertCheckList();
    insertAction.addBeforeRule((IRule)new ValidatorCheckRule(validators));
    insertAction.addBeforeRule((IRule)new MultiCurrencySaveBeforeRule());
    insertAction.addBeforeRule((IRule)new ProjectTSInsertBeforeRule());
    insertAction.addBeforeRule((IRule)new BudgetCtlInsertBeforeRule());
    insertAction.addBeforeRule((IRule)new SetHistorySaveBeforeRule());
    insertAction.addBeforeRule((IRule)new DeptScaleInsertBeforeRule());
    insertAction.addBeforeRule((IRule)new DepUsedFileValueBeforeRule());
    insertAction.addBeforeRule((IRule)new CleanNumNullData());
    insertAction.addBeforeRule((IRule)new DeployFlagInsertBeforeRule());
    insertAction.addBeforeRule((IRule)new CodeInsertBeforeRule());
    insertAction.addBeforeRule((IRule)new ValidatorCheckRule(new Validator[] { (Validator)new CodeValidator() }));
    insertAction.addAfterRule((IRule)new SagaCtrlAfterRule());
    insertAction.addAfterRule((IRule)new CodeInsertAfterRule());
    insertAction.addAfterRule((IRule)new SendMessageToFipInsertAfterRule());
    insertAction.addAfterRule((IRule)new SetHistoryAfterRule());
    insertAction.addAfterRule((IRule)new DeptScaleInsertAfterRule());
    insertAction.addAfterRule((IRule)new LogInsertAfterRule());
    insertAction.addAfterRule((IRule)new DailyLogUpdateAfterRule());
    insertAction.addAfterRule((IRule)new WriteBackBillInsertAfterRule());
    insertAction.addAfterRule((IRule)new PermissionDataChangeRule());
    insertAction.addAfterRule((IRule)new UpdateSrcMsg4CardAfterRule());
  }
  
  public AssetEntiretyVO updateCard(LoginContext context, AssetEntiretyVO entiretyVO) throws BusinessException {
    checkLinkUpdateData(entiretyVO);
    BDVersionValidationUtil.validateSuperVO(new SuperVO[] { (SuperVO)entiretyVO.getCardVO() });
    BDVersionValidationUtil.validateSuperVO((SuperVO[])entiretyVO.getCardhistoryVOs());
    UFDoubleUtils.changeNullData(new AMSuperVO[] { (AMSuperVO)entiretyVO.getCardVO() });
    UFDoubleUtils.changeNullData((AMSuperVO[])entiretyVO.getCardhistoryVOs());
    AggCardVO vo = CardVOUtils.changeAssetEntiretyVOTOAggCardVO(entiretyVO);
    Object obj = entiretyVO.getSpecialValue(BudgetControlConst.budgetOtherField);
    if (obj != null && obj instanceof nc.vo.fa.tbb.ControlRule)
      vo.getParentVO().setAttributeValue(BudgetControlConst.budgetOtherField, obj); 
    boolean isEditCategory = ((Boolean)entiretyVO.getSpecialValue(AssetUseConst.editCategoryWhenUpdate)).booleanValue();
    vo.getParentVO().setAttributeValue(AssetUseConst.editCategoryWhenUpdate, Boolean.valueOf(isEditCategory));
    CardVOUtils.fillAggCardVOTabData(vo);
    updateCardVO(new AggCardVO[] { vo });
    AssetEntiretyVO returnData = CardVOUtils.changeAggCardVOTOAssetEntiretyVO(vo);
    SuperVO[] oldaltervo = entiretyVO.getTabVO(CardTabConst.alter);
    Map<String, SuperVO> newMap = new HashMap<>();
    if (oldaltervo != null && oldaltervo.length > 0)
      for (SuperVO singlevo : oldaltervo) {
        String pk_logalter = (String)singlevo.getAttributeValue("pk_logalter");
        if (pk_logalter != null)
          newMap.put(pk_logalter, singlevo); 
      }  
    SuperVO[] alterVo = returnData.getTabVO(CardTabConst.alter);
    if (alterVo != null && alterVo.length > 0)
      for (SuperVO singleNewvo : alterVo) {
        String pk_new_alter = (String)singleNewvo.getAttributeValue("pk_logalter");
        if (newMap.get(pk_new_alter) != null) {
          String bill_type = (String)((SuperVO)newMap.get(pk_new_alter)).getAttributeValue("bill_type");
          if (bill_type != null)
            singleNewvo.setAttributeValue("bill_type", bill_type); 
        } 
      }  
    LockManager.releasePKLocks(new String[] { vo.getParentVO().getPrimaryKey() }, context.getPk_loginUser());
    return returnData;
  }
  
  private void checkLinkUpdateData(AssetEntiretyVO entiretyVO) throws BusinessException {
    CardhistoryVO[] histvos = entiretyVO.getCardhistoryVOs();
    List<CardhistoryVO> volist = new ArrayList<>();
    CardhistoryVO[] newhistvos = queryAllBookCardhistory(entiretyVO.getCardVO().getPk_card());
    for (CardhistoryVO hisvo : histvos) {
      String tpk_accbook = hisvo.getPk_accbook();
      if (!hisvo.getLaststate_flag().booleanValue()) {
        for (CardhistoryVO newhisvo : newhistvos) {
          String npk_accbook = newhisvo.getPk_accbook();
          if (tpk_accbook.equals(npk_accbook))
            volist.add(newhisvo); 
        } 
      } else {
        volist.add(hisvo);
      } 
    } 
    entiretyVO.setCardhistoryVOs(volist.<CardhistoryVO>toArray(new CardhistoryVO[0]));
  }
  
  public void updateCardVO(AggCardVO[] aggvo) throws BusinessException {
    updateBillVO(aggvo, (AggCardVO[])null);
  }
  
  public AggCardVO[] updateBillVO(AggCardVO[] billVOs, AggCardVO[] originBillVOs) throws BusinessException {
    AssertUtils.isTrue(ArrayUtils.isNotEmpty((Object[])billVOs), "updateBillVO");
    SuperVO[] headVOs = BaseVOUtils.getHeadVOs((AggregatedValueObject[])billVOs);
    AuditInfoUtil.updateData(headVOs);
    UpdateActionTemplate<AggCardVO> template = new AssetUpdateActionTemplate<>(billVOs);
    template.setOriginVos(originBillVOs);
    initUpdateActionRules((IActionTemplate<AggCardVO>)template);
    return (AggCardVO[])template.execute();
  }
  
  private List<Validator> getUpdateCheckList() {
    List<Validator> validators = new ArrayList<>();
    validators.add(new CodeValidator());
    validators.add(new MinUnClosedValidator());
    validators.add(new DeptSealValidator());
    validators.add(new NumericValidator());
    validators.add(new UsingStatusValidator());
    validators.add(new AccbookValidator());
    validators.add(new WorkLoanValidator());
    validators.add(new AppBillValidator());
    validators.add(new ProfitBillValidator());
    validators.add(new VoucherDepValidator());
    validators.add(new DepDateValidator());
    validators.add(new TransAssetBillValidator());
    return validators;
  }
  
  protected void initUpdateActionRules(IActionTemplate<AggCardVO> updateAction) {
    super.initUpdateActionRules(updateAction);
    //add by djy 20220228 检验下游的单据
    updateAction.addBeforeRule((IRule)new BeforeCheckDownstream());
    updateAction.addBeforeRule((IRule)new CodeUpdateRule());
    updateAction.addBeforeRule((IRule)new VoStatusSetBeforeRule(1));
    updateAction.addBeforeRule((IRule)new TabCardKeyUpdateBeforeRule());
    updateAction.addBeforeRule((IRule)new CodeUpdateRule());
    List<Validator> validators = getUpdateCheckList();
    updateAction.addBeforeRule((IRule)new ValidatorCheckRule(validators));
    updateAction.addBeforeRule((IRule)new BudgetCtlUpdateBeforeRule());
    updateAction.addBeforeRule((IRule)new DeptScaleUpdateBeforeRule());
    updateAction.addBeforeRule((IRule)new SetHistoryUpdateBeforeRule());
    updateAction.addBeforeRule((IRule)new DepUsedFileValueBeforeRule());
    updateAction.addBeforeRule((IRule)new MultiCurrencySaveBeforeRule());
    updateAction.addBeforeRule((IRule)new CleanNumNullData());
    updateAction.addBeforeRule((IRule)new DelHistoryDBDataUpdateBeforeRule());
    updateAction.addBeforeRule((IRule)new BackupSynchroUpdateBeforeRule());
    updateAction.addAfterRule((IRule)new SagaCtrlAfterRule());
    updateAction.addAfterRule((IRule)new SendMessageToFipUpdateAfterRule());
    updateAction.addAfterRule((IRule)new DeptScaleInsertAfterRule());
    updateAction.addAfterRule((IRule)new LogUpdateAfterRule());
    updateAction.addAfterRule((IRule)new DailyLogUpdateAfterRule());
    updateAction.addAfterRule((IRule)new CategoryChangeLogAfterRule());
    updateAction.addAfterRule((IRule)new WriteBackBillUpdateAfterRule());
    updateAction.addAfterRule((IRule)new SetHistoryAfterRule());
    updateAction.addAfterRule((IRule)new PermissionDataChangeRule());
  }
  
  public AggCardVO deleteCard(LoginContext context, CardVO vo) throws BusinessException {
    BDPKLockUtil.lockSuperVO(new SuperVO[] { (SuperVO)vo });
    BDVersionValidationUtil.validateSuperVO(new SuperVO[] { (SuperVO)vo });
    AggCardVO aggvo = getAggCardVOWhenLast(vo.getPrimaryKey());
    if (null == aggvo)
      ExceptionUtils.asBusinessException(NCLangRes4VoTransl.getNCLangRes().getStrByID("facard_0", "02012005-0683")); 
    List<Validator> validators = getDeleteCheckList();
    checkvalidate(aggvo, validators);
    String nextBillHanler = (new AccbookNextHandleQueryFactory()).queryCardDeleteAble(aggvo, false);
    if (nextBillHanler != null && nextBillHanler.length() > 0)
      ExceptionUtils.asBusinessException(nextBillHanler); 
    ((IAsset)AMProxy.lookup(IAsset.class)).deleteCardVO(aggvo);
    AggCardVO newBill = (AggCardVO)Constructor.construct(aggvo.getClass());
    SuperVO headVO = createSkeleton((SuperVO)aggvo.getParentVO(), new String[] { "pk_card" });
    SuperVO[] hisVOs = aggvo.getTableVO(CardTabConst.history);
    List<SuperVO> newHisVOs = new ArrayList<>();
    for (SuperVO hisVO : hisVOs) {
      SuperVO newHis = createSkeleton(hisVO, new String[] { "pk_card", "pk_cardhistory", "pk_accbook" });
      newHisVOs.add(newHis);
    } 
    newBill.setParentVO((CircularlyAccessibleValueObject)headVO);
    newBill.setTableVO(CardTabConst.history, (CircularlyAccessibleValueObject[])CollectionUtils.toArray(newHisVOs));
    return newBill;
  }
  
  public void deleteCardVO(AggCardVO aggvo) throws BusinessException {
    deleteBillVO(new AggCardVO[] { aggvo });
  }
  
  private List<Validator> getDeleteCheckList() {
    List<Validator> validators = new ArrayList<>();
    validators.add(new MinUnClosedValidator());
    validators.add(new VoucherDepValidator());
    validators.add(new VoucherAddValidator());
    validators.add(new NextHandlerValidator());
    validators.add(new RentOutDataValidator());
    validators.add(new ExpenseOutDataValidator());
    return validators;
  }
  
  public void deleteCard(AggCardVO[] billVOs) throws BusinessException {
    List<Validator> validators = getDeleteCheckList();
    checkvalidate(billVOs, validators);
    deleteBillVO(billVOs);
  }
  
  private SuperVO createSkeleton(SuperVO vo, String[] fieldNames) {
    SuperVO newVO = (SuperVO)Constructor.construct(vo.getClass());
    Set<String> attrSet = new HashSet<>();
    attrSet.addAll(Arrays.asList(fieldNames));
    IAttributeMeta keyAttr = vo.getMetaData().getPrimaryAttribute();
    attrSet.add(keyAttr.getName());
    attrSet.add("ts");
    for (String name : attrSet) {
      Object value = vo.getAttributeValue(name);
      ((AMSuperVO)newVO).setAttributeValue(name, value, true);
    } 
    return newVO;
  }
  
  protected void initDeleteActionRules(IActionTemplate<AggCardVO> deleteAction) {
    super.initDeleteActionRules(deleteAction);
    deleteAction.addBeforeRule((IRule)new VOSagasStatusCheckBeforeRule());
    deleteAction.addBeforeRule((IRule)new VoStatusSetBeforeRule(3));
    deleteAction.addBeforeRule((IRule)new SetHistoryDeleteBeforeRule());
    deleteAction.addBeforeRule((IRule)new DeptScaleDeleteBeforeRule());
    deleteAction.addBeforeRule((IRule)new BudgetCtlDeleteBeforeRule());
    deleteAction.addAfterRule((IRule)new SagaCtrlAfterRule());
    deleteAction.addAfterRule((IRule)new SendMessageToFipDeleteAfterRule());
    deleteAction.addAfterRule((IRule)new CodeDeleteRule());
    deleteAction.addAfterRule((IRule)new LogDeleteAfterRule());
    deleteAction.addAfterRule((IRule)new WriteBackBillDeleteAfterRule());
    deleteAction.addAfterRule((IRule)new PermissionDataChangeRule());
    deleteAction.addAfterRule((IRule)new BackupSynchroDeleteAfterRule());
  }
  
  protected void checkvalidate(Object datas, List<Validator> validators) throws ValidationException {
    if (validators != null && validators.size() > 0) {
      IValidationService validation = ValidationFrameworkUtil.createValidationService(validators.<Validator>toArray(new Validator[0]));
      validation.validate(datas);
    } 
  }
  
  private AggAssetVO[] queryAggAssetVOByHistory(String[] pk_cardhistorys) throws BusinessException {
    String sql = "pk_cardhistory in" + InSqlManager.getInSQLValue(pk_cardhistorys);
    AggAssetVO[] aggAvos = queryAggAssetVOBySql(sql);
    return aggAvos;
  }
  
  private AggAssetVO[] queryAggAssetVOBySql(String sql) throws BusinessException {
    AssetVO[] vos = queryAssetVOBySQL(sql);
    if (vos == null || vos.length == 0)
      ExceptionUtils.asBusinessException(NCLangRes4VoTransl.getNCLangRes().getStrByID("facard_0", "02012005-0412")); 
    List<AggAssetVO> aggvos = new ArrayList<>();
    for (int i = 0; i < vos.length; i++) {
      CardVOUtils.countFinanceFieldValue((SuperVO)vos[i]);
      AggAssetVO vo = new AggAssetVO();
      vo.setParentVO((CircularlyAccessibleValueObject)vos[i]);
      aggvos.add(vo);
    } 
    AggAssetVO[] aggAvos = aggvos.<AggAssetVO>toArray(new AggAssetVO[0]);
    fillUsedeptValue(aggAvos);
    return aggAvos;
  }
  
  public AggAssetVO[] queryAggAssetVOByClientKeys(String[] pks) throws BusinessException {
    if (pks == null || pks.length == 0)
      return null; 
    List<String> linkpks = new ArrayList<>();
    for (String pk : pks) {
      if (StringUtils.isNotEmpty(pk) && pk
        .indexOf("#") > -1) {
        pk = pk.replace("#", AssetUseConst.clientKeyLinkString);
        linkpks.add(pk);
      } else {
        linkpks.add(pk);
      } 
    } 
    pks = linkpks.<String>toArray(new String[0]);
    Map<String, List<String>> accbook_card = new HashMap<>();
    StringBuffer sql = new StringBuffer();
    sql.append("(");
    sql.append("laststate_flag = '" + UFBoolean.TRUE + "'");
    sql.append(" or ");
    sql.append("(");
    sql.append("asset_state in " + InSqlManager.getInSQLValue(AssetStateConst.getReduceStateList()));
    sql.append(" and laststate_flag = '" + UFBoolean.FALSE + "'");
    sql.append(")");
    sql.append(")");
    sql.append(" and ");
    if (pks[0].indexOf(AssetUseConst.clientKeyLinkString) > 0) {
      for (int i = 0; i < pks.length; i++) {
        String[] keys = pks[i].split(AssetUseConst.clientKeyLinkString);
        String pk_card = keys[0];
        String pk_accbook = keys[1];
        if (accbook_card.containsKey(pk_accbook)) {
          ((List<String>)accbook_card.get(pk_accbook)).add(pk_card);
        } else {
          List<String> card = new ArrayList<>();
          card.add(pk_card);
          accbook_card.put(pk_accbook, card);
        } 
      } 
      StringBuffer sb = new StringBuffer();
      sb.append("(");
      for (String pk_accbook : accbook_card.keySet()) {
        sb.append(" or ");
        sb.append("(");
        sb.append("pk_card in" + InSqlManager.getInSQLValue(accbook_card.get(pk_accbook)));
        sb.append(" and pk_accbook = '" + pk_accbook + "'");
        sb.append(")");
      } 
      sb.delete(1, 5);
      sql.append(sb);
    } else {
      sql.append("(");
      sql.append(" pk_card in" + InSqlManager.getInSQLValue(pks));
    } 
    sql.append(")");
    AggAssetVO[] aggAvos = queryAggAssetVOBySql(sql.toString());
    return aggAvos;
  }
  
  public AssetEntiretyVO queryAboutAsset(LinkQueryAssetData queryAssetData) throws BusinessException {
    AssetEntiretyVO entiretyVO = null;
    if (StringUtils.isNotEmpty(queryAssetData.getPk_cardhistory())) {
      entiretyVO = queryAboutAssetByHistory(queryAssetData.getBillID(), queryAssetData.getPk_cardhistory());
    } else if (queryAssetData.getAccyear() != null && queryAssetData.getAccmonth() != null) {
      entiretyVO = queryAboutAssetByPeriod(queryAssetData.getBillID(), queryAssetData.getPk_accbook(), queryAssetData.getAccyear(), queryAssetData
          .getAccmonth());
    } else {
      entiretyVO = queryAboutAssetByBusinessDate(queryAssetData.getBillID(), queryAssetData.getPk_accbook(), queryAssetData
          .getBusi_date());
    } 
    return entiretyVO;
  }
  
  private AssetEntiretyVO queryAboutAssetByHistory(String pk_card, String pk_cardhistory) throws BusinessException {
    String[] pk_accbooks = queryAccbookByCardKey(pk_card);
    String[] queryFiles = { "pk_accbook", "pk_cardhistory" };
    CardhistoryVO[] hisVOs = (CardhistoryVO[])QueryUtil.querySuperVOByPks(CardhistoryVO.class, queryFiles, new String[] { pk_cardhistory });
    if (ArrayUtils.isEmpty((Object[])hisVOs))
      return null; 
    StringBuffer whereSql = new StringBuffer();
    whereSql.append(" dr = 0");
    whereSql.append(" and pk_card = '" + pk_card + "'");
    whereSql.append(" and ");
    whereSql.append("(");
    whereSql.append("pk_cardhistory = '" + pk_cardhistory + "'");
    String[] otherAccbooks = (String[])ArrayUtils.remove((Object[])pk_accbooks, hisVOs[0].getPk_accbook());
    if (ArrayUtils.isNotEmpty((Object[])otherAccbooks)) {
      whereSql.append(" or (");
      whereSql.append("pk_accbook in " + InSqlManager.getInSQLValue(otherAccbooks));
      whereSql.append(" and " + AssetStateConst.getNewestAssetSql(false));
      whereSql.append(")");
    } 
    whereSql.append(")");
    AssetVO[] vos = queryAssetVOBySQL(whereSql.toString());
    AssetEntiretyVO entiretyVO = changeVOtypeWhenQueryAbout(vos);
    return entiretyVO;
  }
  
  private AssetEntiretyVO queryAboutAssetByBusinessDate(String pk_card, String pk_accbook, UFDate business_date) throws BusinessException {
    String[] pk_accbooks = null;
    if (AccbookManager.isBizAccbook(pk_accbook)) {
      pk_accbooks = queryAccbookByCardKey(pk_card);
    } else {
      pk_accbooks = new String[] { pk_accbook };
    } 
    if (pk_accbook == null || pk_accbook.length() == 0)
      return null; 
    StringBuffer whereSql = new StringBuffer();
    whereSql.append(" dr = 0");
    whereSql.append(" and pk_card ='" + pk_card + "'");
    if (business_date == null) {
      whereSql.append(" and pk_accbook in" + InSqlManager.getInSQLValue(pk_accbooks));
      whereSql.append(" and " + AssetStateConst.getNewestAssetSql(false));
    } else {
      whereSql.append(" and " + AssetHelperHandleUtil.getQueryCardhistorySql(business_date, null, pk_accbooks));
    } 
    AssetVO[] vos = queryAssetVOBySQL(whereSql.toString());
    AssetEntiretyVO entiretyVO = changeVOtypeWhenQueryAbout(vos);
    return entiretyVO;
  }
  
  private AssetEntiretyVO queryAboutAssetByPeriod(String pk_card, String pk_accbook, String accyear, String accmonth) throws BusinessException {
    String[] pk_accbooks = null;
    if (AccbookManager.isBizAccbook(pk_accbook)) {
      pk_accbooks = queryAccbookByCardKey(pk_card);
    } else {
      pk_accbooks = new String[] { pk_accbook };
    } 
    if (pk_accbook == null || pk_accbook.length() == 0)
      return null; 
    StringBuffer whereSql = new StringBuffer();
    whereSql.append(" dr = 0");
    whereSql.append(" and pk_card ='" + pk_card + "'");
    whereSql.append(" and " + AssetHelperHandleUtil.getQueryCardhistorySql(accyear, accmonth, null, new String[] { pk_accbook }));
    String[] otherAccbooks = (String[])ArrayUtils.remove((Object[])pk_accbooks, pk_accbook);
    if (ArrayUtils.isNotEmpty((Object[])otherAccbooks)) {
      whereSql.append(" and (");
      whereSql.append("pk_accbook in " + InSqlManager.getInSQLValue(otherAccbooks));
      whereSql.append(" and " + AssetStateConst.getNewestAssetSql(false));
      whereSql.append(")");
    } 
    AssetVO[] vos = queryAssetVOBySQL(whereSql.toString());
    AssetEntiretyVO entiretyVO = changeVOtypeWhenQueryAbout(vos);
    return entiretyVO;
  }
  
  private AssetEntiretyVO changeVOtypeWhenQueryAbout(AssetVO[] vos) throws BusinessException {
    if (vos == null || vos.length == 0)
      return null; 
    fillUsedeptValue(vos);
    List<CardhistoryVO> hisVOList = new ArrayList<>();
    for (int i = 0; i < vos.length; i++) {
      CardVOUtils.countFinanceFieldValue((SuperVO)vos[i]);
      hisVOList.add(CardVOUtils.getCardhistoryVOFromHeadVO(vos[i]));
    } 
    AssetEntiretyVO entiretyVO = new AssetEntiretyVO();
    CardVO cVO = CardVOUtils.getCardVOFromHeadVO(vos[0]);
    CardhistoryVO[] hisVOs = hisVOList.<CardhistoryVO>toArray(new CardhistoryVO[0]);
    entiretyVO.setCardVO(cVO);
    entiretyVO.setCardhistoryVOs(hisVOs);
    fillBodyVOs(entiretyVO);
    return entiretyVO;
  }
  
  private void fillUsedeptValue(AggAssetVO[] aggAvos) throws BusinessException {
    SuperVO[] headVos = BaseVOUtils.getHeadVOs((AggregatedValueObject[])aggAvos);
    String[] link_keys = BaseVOUtils.getVOAttributeNotNullValues(headVos, "pk_usedept");
    Map<String, List<DeptScaleVO>> mutilUsedeptVOs = UseDeptScaleUtils.queryDeptScaleBatch(link_keys);
    for (AggAssetVO aggAvo : aggAvos) {
      AssetVO avo = (AssetVO)aggAvo.getParentVO();
      String pk_usedept = (String)avo.getAttributeValue("pk_usedept");
      if (StringUtils.isEmpty(pk_usedept) || mutilUsedeptVOs == null || mutilUsedeptVOs.size() == 0) {
        avo.setAttributeValue("usedep_flag", UFBoolean.FALSE);
      } else {
        List<DeptScaleVO> deptVos = mutilUsedeptVOs.get(pk_usedept);
        if (deptVos == null) {
          avo.setAttributeValue("usedep_flag", UFBoolean.FALSE);
        } else if (deptVos.size() > 1) {
          avo.setAttributeValue("usedep_flag", UFBoolean.TRUE);
          String showName = UseDeptScaleUtils.getShowName((DeptScaleVO[])CollectionUtils.toArray(deptVos));
          avo.setPk_usedept(showName);
        } else if (deptVos.size() == 1) {
          avo.setAttributeValue("usedep_flag", UFBoolean.FALSE);
          avo.setAttributeValue("pk_usedept", ((DeptScaleVO)deptVos.get(0)).getPk_dept());
        } 
        try {
          SuperVO[] viewVos = CardVOUtils.changeTrueTabVOToViewTabVO((SuperVO[])CollectionUtils.toArray(deptVos));
          aggAvo.setTableVO(CardTabConst.useDept, (CircularlyAccessibleValueObject[])viewVos);
        } catch (NullPointerException e) {
          Logger.info(e.getMessage());
        } 
      } 
    } 
  }
  
  private void fillUsedeptValue(AssetVO[] vos) throws BusinessException {
    List<String> pk_usedept = new ArrayList<>();
    for (int i = 0; i < vos.length; i++) {
      if (vos[i].getPk_usedept() != null)
        pk_usedept.add(vos[i].getPk_usedept()); 
    } 
    Map<String, List<DeptScaleVO>> deptMap = null;
    if (pk_usedept.size() > 0)
      deptMap = UseDeptScaleUtils.queryDeptScaleBatch(pk_usedept.<String>toArray(new String[0])); 
    if (deptMap != null && deptMap.size() > 0)
      for (AssetVO vo : vos) {
        String link_key = vo.getPk_usedept();
        List<DeptScaleVO> depList = deptMap.get(link_key);
        if (depList == null || depList.size() == 0) {
          vo.setAttributeValue("usedep_flag", UFBoolean.FALSE);
        } else if (depList.size() > 1) {
          vo.setAttributeValue("usedep_flag", UFBoolean.TRUE);
          String showName = UseDeptScaleUtils.getShowName((DeptScaleVO[])CollectionUtils.toArray(depList));
          vo.setPk_usedept(showName);
        } else if (depList.size() == 1) {
          vo.setAttributeValue("usedep_flag", UFBoolean.FALSE);
          vo.setAttributeValue("pk_usedept", ((DeptScaleVO)depList.get(0)).getPk_dept());
        } 
      }  
  }
  
  public String[] queryPksByWhereSql(String whereSql) throws BusinessException {
    StringBuffer sql = new StringBuffer();
    sql.append("select fa_card.pk_org, fa_card.card_code, ");
    sql.append(" (fa_cardhistory.pk_card || '");
    sql.append(AssetUseConst.clientKeyLinkString);
    sql.append("' || fa_cardhistory.pk_accbook) clientKey");
    sql.append(" from ");
    sql.append(whereSql);
    sql.append(" and fa_cardhistory.dr = 0");
    sql.append(" and fa_card.dr = 0");
    String pk_group = InvocationInfoProxy.getInstance().getGroupId();
    sql.append(" and fa_card.pk_group = '" + pk_group + "'");
    sql.append(" group by fa_card.pk_org, fa_card.card_code, ");
    sql.append(" fa_cardhistory.pk_card || '");
    sql.append(AssetUseConst.clientKeyLinkString);
    sql.append("' || fa_cardhistory.pk_accbook ");
    sql.append(" order by fa_card.pk_org asc, fa_card.card_code asc, clientkey asc");
    List<String> result = (List<String>)this.dbUtil.executeQuery(sql.toString(), (ResultSetProcessor)new ListStrProcesser());
    if (result != null && result.size() > 0)
      return (String[])CollectionUtils.toArray(result); 
    return null;
  }
  
  public List<Map<String, String>> queryPksByWhereSql4Cloud(String whereSql) throws BusinessException {
    StringBuffer sql = new StringBuffer();
    sql.append("select fa_card.pk_org, fa_card.card_code, ");
    sql.append(" (fa_cardhistory.pk_card || '");
    sql.append(AssetUseConst.clientKeyLinkString);
    sql.append("' || fa_cardhistory.pk_accbook) clientKey");
    sql.append(", fa_cardhistory.pk_cardhistory");
    sql.append(" from ");
    sql.append(whereSql);
    sql.append(" and fa_cardhistory.dr = 0");
    sql.append(" and fa_card.dr = 0");
    String pk_group = InvocationInfoProxy.getInstance().getGroupId();
    sql.append(" and fa_card.pk_group = '" + pk_group + "'");
    sql.append(" order by fa_card.pk_org asc, fa_card.card_code asc, clientkey asc");
    List<Map<String, String>> result = (List<Map<String, String>>)this.dbUtil.executeQuery(sql.toString(), (ResultSetProcessor)new ListMapProcesser());
    return result;
  }
  
  private class ListStrProcesser extends BaseProcessor {
    private static final long serialVersionUID = -3517546661547273794L;
    
    private ListStrProcesser() {}
    
    public Object processResultSet(ResultSet rs) throws SQLException {
      List<String> results = new ArrayList<>();
      while (rs.next()) {
        String str = rs.getString("clientKey");
        results.add(str);
      } 
      return results;
    }
  }
  
  private class ListMapProcesser extends BaseProcessor {
    private static final long serialVersionUID = -3518966661547273794L;
    
    private ListMapProcesser() {}
    
    public Object processResultSet(ResultSet rs) throws SQLException {
      List<Map<String, String>> results = new ArrayList<>();
      while (rs.next()) {
        Map<String, String> map = new HashMap<>();
        map.put(AssetUseConst.CLIENTKEY, rs.getString("clientKey"));
        map.put("pk_cardhistory", rs.getString("pk_cardhistory"));
        results.add(map);
      } 
      return results;
    }
  }
  
  public AssetVO[] queryAssetVOBySQL(String whereSql) throws BusinessException {
    String adjustWhere = AssetQuerySqlTool.adjustWhereSQL(whereSql);
    String sql = AssetQuerySqlTool.buildQuerySql(adjustWhere, null, new String[] { "fa_card.pk_org asc", "fa_card.card_code asc", "fa_cardhistory.pk_accbook asc" });
    return (AssetVO[])this.dbUtil.executeQuery(sql, (ResultSetProcessor)new AssetProcessor());
  }
  
  private String[] queryAccbookByCardKey(String pk_card) throws BusinessException {
    String sqlAccbook = "select distinct pk_accbook from fa_cardhistory where pk_card = '" + pk_card + "'";
    Set<String> pk_accbooks = (Set<String>)this.dbUtil.executeQuery(sqlAccbook, (ResultSetProcessor)new ColumnSetProcessor("pk_accbook"));
    if (pk_accbooks != null && pk_accbooks.size() > 0)
      return pk_accbooks.<String>toArray(new String[0]); 
    return null;
  }
  
  public CardhistoryVO[] queryAllBookCardhistory(String pk_card) throws BusinessException {
    if (pk_card == null)
      return null; 
    StringBuffer queryHistoryDataSql = new StringBuffer();
    queryHistoryDataSql.append(" pk_card = '" + pk_card + "'");
    queryHistoryDataSql.append(" and (laststate_flag = '" + UFBoolean.TRUE + "' or " + "asset_state" + " in" + 
        InSqlManager.getInSQLValue(AssetStateConst.getReduceStateList()) + ")");
    String cuserid = InvocationInfoProxy.getInstance().getUserId();
    String pk_group = InvocationInfoProxy.getInstance().getGroupId();
    String[] powerAccbookPks = AccbookPowerUtil.queryPowerAccbookPk(pk_group, cuserid);
    if (!AccbookPowerUtil.isNotStartPower(powerAccbookPks)) {
      if (powerAccbookPks == null || powerAccbookPks.length == 0) {
        Logger.error("没有账簿数据权限");
        ExceptionUtils.asBusinessException(NCLangRes4VoTransl.getNCLangRes().getStrByID("facard_0", "02012005-0413"));
      } 
      queryHistoryDataSql.append(" and pk_accbook in" + InSqlManager.getInSQLValue(powerAccbookPks));
    } 
    CardhistoryVO[] hisVOs = (CardhistoryVO[])QueryUtil.queryVOByCond(CardhistoryVO.class, queryHistoryDataSql.toString(), null);
    if (hisVOs != null && hisVOs.length > 0) {
      String link_key = hisVOs[0].getPk_usedept();
      DeptScaleVO[] deptscaleVOs = UseDeptScaleUtils.queryUseDeptByLink(new String[] { link_key });
      String pk_usedept = null;
      UFBoolean Usedep_flag = UFBoolean.FALSE;
      if (deptscaleVOs != null && deptscaleVOs.length == 1) {
        pk_usedept = deptscaleVOs[0].getPk_dept();
      } else if (deptscaleVOs != null && deptscaleVOs.length > 1) {
        pk_usedept = link_key;
        Usedep_flag = UFBoolean.TRUE;
      } 
      for (CardhistoryVO hisVO : hisVOs) {
        hisVO.setPk_usedept(pk_usedept);
        hisVO.setUsedep_flag(Usedep_flag);
      } 
    } 
    return hisVOs;
  }
  
  public AssetEntiretyVO refreshDataByPk(String pk) throws BusinessException {
    AssetEntiretyVO entiretyVO = new AssetEntiretyVO();
    CardhistoryVO[] hisVOs = queryAllBookCardhistory(pk);
    if (hisVOs == null || hisVOs.length == 0)
      return null; 
    String pk_card = hisVOs[0].getPk_card();
    CardVO[] cVOs = (CardVO[])QueryUtil.querySuperVOByPks(CardVO.class, new String[] { pk_card });
    if (cVOs == null || cVOs.length == 0)
      return null; 
    entiretyVO.setCardhistoryVOs(hisVOs);
    entiretyVO.setCardVO(cVOs[0]);
    fillBodyVOs(entiretyVO);
    return entiretyVO;
  }
  
  private void fillBodyVOs(AssetEntiretyVO entiretyVO) throws BusinessException {
    String pk_card = entiretyVO.getCardVO().getPk_card();
    String pk_group = entiretyVO.getCardVO().getPk_group();
    String pk_org = entiretyVO.getCardVO().getPk_org();
    CardhistoryVO[] hisVOs = entiretyVO.getCardhistoryVOs();
    IBean assetBean = MDBaseQueryFacade.getInstance().getBeanByFullClassName(AssetVO.class.getName());
    List<IBean> bodyBeans = assetBean.getRelatedEntities(AssociationKind.Composite, 2);
    if (bodyBeans != null && bodyBeans.size() > 0)
      for (IBean bean : bodyBeans) {
        String className = bean.getFullClassName();
        String tabCode = AssetTabConstManager.getTabCodeByClassName(className);
        if (tabCode.equals(CardTabConst.history))
          continue; 
        List<SuperVO> tabVOs = new ArrayList<>();
        QueryTabDataContext tabContext = new QueryTabDataContext();
        tabContext.setPk_cards(new String[] { pk_card });
        tabContext.setTabCode(tabCode);
        tabContext.setPk_group(pk_group);
        tabContext.setPk_org(pk_org);
        if (tabCode.equals(CardTabConst.useDept)) {
          tabContext.setUseObject(hisVOs[0].getPk_cardhistory());
          SuperVO[] vos = queryBodyVOs(tabContext);
          if (vos != null && vos.length > 0)
            tabVOs.addAll(Arrays.asList(vos)); 
          if (ArrayUtils.getLength(vos) == 1) {
            String pk_usedept = (String)vos[0].getAttributeValue("pk_dept");
            for (int i = 0; i < hisVOs.length; i++) {
              hisVOs[i].setPk_usedept(pk_usedept);
              hisVOs[i].setUsedep_flag(UFBoolean.FALSE);
            } 
          } 
        } else {
          for (int i = 0; i < hisVOs.length; i++) {
            tabContext.setPk_accbook(hisVOs[i].getPk_accbook());
            SuperVO[] vos = queryBodyVOs(tabContext);
            String ttabCode = tabContext.getTabCode();
            if (vos != null && vos.length > 0) {
              List<String> hasKey = BaseVOUtils.getBaseVOIDsWithNotNull((CircularlyAccessibleValueObject[])CollectionUtils.toArray(tabVOs));
              for (SuperVO vo : vos) {
                if (CardTabConst.deploy.equals(ttabCode) || CardTabConst.subequip
                  .equals(ttabCode) || CardTabConst.insurance
                  .equals(ttabCode) || CardTabConst.rent
                  .equals(ttabCode) || CardTabConst.expense
                  .equals(ttabCode)) {
                  if (!hasKey.contains(vo.getPrimaryKey()))
                    tabVOs.add(vo); 
                } else {
                  tabVOs.add(vo);
                } 
              } 
            } 
          } 
        } 
        entiretyVO.setTabVO(tabCode, tabVOs.<SuperVO>toArray(new SuperVO[0]));
      }  
  }
  
  private void fillBodyVOs(AggAssetVO[] aggAvos) throws BusinessException {
    Map<List<Object>, List<AggAssetVO>> bookDatas = BaseVOUtils.groupingBillToMap(aggAvos, new String[] { "pk_accbook" });
    for (List<Object> key : bookDatas.keySet()) {
      List<AggAssetVO> bookData = bookDatas.get(key);
      String pk_accbook = (String)key.get(0);
      fillBodyVOs(bookData.<AggAssetVO>toArray(new AggAssetVO[0]), pk_accbook);
    } 
  }
  
  private void fillBodyVOs(AggAssetVO[] aggAvos, String pk_accbook) throws BusinessException {
    Map<List<Object>, List<AggAssetVO>> groupDatas = BaseVOUtils.groupingBillToMap(aggAvos, new String[] { "pk_org" });
    for (List<Object> key : groupDatas.keySet()) {
      List<AggAssetVO> groupData = groupDatas.get(key);
      String[] pk_cards = BaseVOUtils.getBillIds((AggregatedValueObject[])CollectionUtils.toArray(groupData));
      QueryTabDataContext context = new QueryTabDataContext();
      context.setPk_accbook(pk_accbook);
      context.setPk_cards(pk_cards);
      context.setPk_group(InvocationInfoProxy.getInstance().getGroupId());
      String pk_org = (String)((AggAssetVO)groupData.get(0)).getParentVO().getAttributeValue("pk_org");
      context.setPk_org(pk_org);
      for (String tabCode : CardTabConst.allTab) {
        if (!tabCode.equals(CardTabConst.useDept)) {
          context.setTabCode(tabCode);
          SuperVO[] bodyTabVos = queryBodyVOs(context);
          if (ArrayUtils.isNotEmpty((Object[])bodyTabVos)) {
            Map<String, List<SuperVO>> bodyMaps = BaseVOUtils.groupingVOsToMap(bodyTabVos, new String[] { "pk_card" });
            for (String pk_card : bodyMaps.keySet()) {
              List<SuperVO> bodyVOs = bodyMaps.get(pk_card);
              if (bodyVOs != null && bodyVOs.size() > 0)
                for (AggAssetVO aggAvo : groupData) {
                  if (aggAvo.getPrimaryKey().equals(pk_card))
                    aggAvo.setTableVO(tabCode, (CircularlyAccessibleValueObject[])CollectionUtils.toArray(bodyVOs)); 
                }  
            } 
          } 
        } 
      } 
    } 
  }
  
  public SuperVO[] queryBodyVOs(QueryTabDataContext tabContext) throws BusinessException {
    SuperVO[] bodyVOs = null;
    if (tabContext.getTabCode() == null)
      return bodyVOs; 
    List<IQueryAssetTabDataPlugin> plugins = new ArrayList<>();
    if (tabContext.getTabCode().equals(CardTabConst.alter)) {
      plugins.add(new AssetAlterTabQuery());
    } else if (tabContext.getTabCode().equals(CardTabConst.dep)) {
      plugins.add(new AssetDepTabQuery());
    } else if (tabContext.getTabCode().equals(CardTabConst.reduce)) {
      plugins.add(new AssetReduceTabQuery());
    } else if (tabContext.getTabCode().equals(CardTabConst.deploy)) {
      plugins.add(new AssetDeployTabQuery());
    } else if (tabContext.getTabCode().equals(CardTabConst.evaluate)) {
      plugins.add(new AssetEvaluateTabQuery());
    } else if (tabContext.getTabCode().equals(CardTabConst.useDept)) {
      plugins.add(new DeptScaleTabQuery());
    } else if (tabContext.getTabCode().equals(CardTabConst.devalue)) {
      plugins.add(new AssetDevalueTabQuery());
    } else if (tabContext.getTabCode().equals(CardTabConst.expense)) {
      plugins.add(new DefultTabQuery());
    } else if (tabContext.getTabCode().equals(CardTabConst.rent)) {
      plugins.add(new DefultTabQuery());
    } else if (tabContext.getTabCode().equals(CardTabConst.subequip)) {
      plugins.add(new DefultTabQuery());
    } else if (tabContext.getTabCode().equals(CardTabConst.insurance)) {
      plugins.add(new DefultTabQuery());
    } else {
      PluginContext pluginContext = new PluginContext();
      pluginContext.setModule("FA");
      pluginContext.setTag(tabContext.getTabCode());
      pluginContext.setPluginType(PluginTypeConst.queryTabDatasPlugin);
      pluginContext.setExtension_point(ExtensionPointConst.AssetTabData_point);
      plugins = (new PluginServiceImpl()).queryPluginsByTag(pluginContext, IQueryAssetTabDataPlugin.class);
    } 
    if (plugins != null && plugins.size() > 0) {
      List<SuperVO> data = new ArrayList<>();
      for (IQueryAssetTabDataPlugin plugin : plugins) {
        SuperVO[] result = plugin.queryTabDataPlugin(tabContext);
        if (result != null && result.length > 0)
          data.addAll(Arrays.asList(result)); 
      } 
      if (data.size() > 0)
        bodyVOs = data.<SuperVO>toArray(new SuperVO[0]); 
    } 
    return bodyVOs;
  }
  
  public <T extends SuperVO> T[] queryVOByCond(Class<T> voClass, String condition, String[] names, String order) throws BusinessException {
    if (ArrayUtils.isEmpty((Object[])names)) {
      Set<String> fieldNames = MDUtils.getAttributeNames(voClass);
      fieldNames.add("pk_card");
      names = (String[])CollectionUtils.toArray(fieldNames);
    } 
    return (T[])QueryUtil.queryVOByCond(voClass, condition, names, order);
  }
  
  public Map<String, Object> queryNeedDataWhenEdit(String pk_card) throws BusinessException {
    Map<String, Object> result = new HashMap<>();
    CardhistoryVO[] hisVOs = queryEditAbleBookBeginMonthData(pk_card);
    result.put(AssetUseConst.editAbleBookBeginMonthData, hisVOs);
    Map<String, List<DeptScaleVO>> usedeptDatas = AssetUseDeptQuery.queryUseDeptBatch(new String[] { pk_card });
    List<DeptScaleVO> deptScaleVOs = usedeptDatas.get(pk_card);
    SuperVO[] viewVOs = null;
    if (deptScaleVOs != null && deptScaleVOs.size() > 0)
      viewVOs = CardVOUtils.changeTrueTabVOToViewTabVO((SuperVO[])CollectionUtils.toArray(deptScaleVOs)); 
    result.put(AssetUseConst.fillUsedeptData, viewVOs);
    return result;
  }
  
  private CardhistoryVO[] queryEditAbleBookBeginMonthData(String pk_card) throws BusinessException {
    Set<String> editAbleBook = new HashSet<>();
    if (pk_card == null)
      return null; 
    Map<String, UFBoolean> allBooks = AccbookNextHandleQueryFactory.queryAccbookEditable(pk_card);
    if (allBooks == null) {
      LockManager.releasePKLocks(new String[] { pk_card }, null);
      ExceptionUtils.asBusinessException(NCLangRes4VoTransl.getNCLangRes().getStrByID("facard_0", "02012005-0414"));
    } 
    if (allBooks != null && allBooks.size() > 0)
      for (String pk_accbook : allBooks.keySet()) {
        if (allBooks.get(pk_accbook) == UFBoolean.TRUE)
          editAbleBook.add(pk_accbook); 
      }  
    if (editAbleBook != null && editAbleBook.size() > 0) {
      String condition = "pk_card = '" + pk_card + "' and pk_accbook in" + InSqlManager.getInSQLValue(editAbleBook.<String>toArray(new String[0])) + " and laststate_flag = '" + UFBoolean.FALSE + "'";
      String[] queryNames = AssetUseConst.getMonthBeginFieldsWhenEdit();
      CardhistoryVO[] vos = (CardhistoryVO[])QueryUtil.queryVOByCond(CardhistoryVO.class, condition, queryNames, null);
      return vos;
    } 
    return null;
  }
  
  public String getNewAssetsuitCode(String pk_org, String pk_dept) throws BusinessException {
    String codeWay = ParameterManager.getParaString(pk_org, "FA76");
    Integer numLenth = ParameterManager.getParaInt(pk_org, "FA77");
    String codePre = null;
    DeptVO[] deptVOs = ((IDeptPubService)AMProxy.lookup(IDeptPubService.class)).queryDeptVOsByPKS(new String[] { pk_dept });
    if (deptVOs == null || deptVOs.length != 1)
      ExceptionUtils.asBusinessException(NCLangRes4VoTransl.getNCLangRes().getStrByID("facard_0", "02012005-0415")); 
    DeptVO deptVO = deptVOs[0];
    if (codeWay.equals(ParaValueConst.FA76_name_num)) {
      codePre = MultiLanguageUtil.getMultiLanguageValue((SuperVO)deptVO, "name");
    } else if (codeWay.equals(ParaValueConst.FA76_code_num)) {
      codePre = deptVO.getCode();
    } else if (codeWay.equals(ParaValueConst.FA76_def1_num)) {
      codePre = deptVO.getDef1();
      String showName = getDepUserDefValue(pk_org, "1", codePre);
      codePre = showName;
    } else if (codeWay.equals(ParaValueConst.FA76_def2_num)) {
      codePre = deptVO.getDef2();
      String showName = getDepUserDefValue(pk_org, "2", codePre);
      codePre = showName;
    } else if (codeWay.equals(ParaValueConst.FA76_def3_num)) {
      codePre = deptVO.getDef3();
      String showName = getDepUserDefValue(pk_org, "3", codePre);
      codePre = showName;
    } else if (codeWay.equals(ParaValueConst.FA76_def4_num)) {
      codePre = deptVO.getDef4();
      String showName = getDepUserDefValue(pk_org, "4", codePre);
      codePre = showName;
    } else if (codeWay.equals(ParaValueConst.FA76_def5_num)) {
      codePre = deptVO.getDef5();
      String showName = getDepUserDefValue(pk_org, "5", codePre);
      codePre = showName;
    } 
    if (null == codePre)
      codePre = ""; 
    String sql = "select max(assetsuit_code) from fa_card where dr=0 and pk_org = '" + pk_org + "' and assetsuit_code like '" + codePre + "%'";
    Set<String> maxCodeSet = (Set<String>)this.dbUtil.executeQuery(sql, (ResultSetProcessor)new ColumnSetProcessor());
    StringBuffer newCode = new StringBuffer();
    newCode.append(codePre);
    if (maxCodeSet == null || maxCodeSet.size() == 0) {
      for (int i = 0; i < numLenth.intValue() - 1; i++)
        newCode.append("0"); 
      newCode.append("1");
    } else {
      int iLen = 1;
      int inewIndex = 1;
      String maxCode = maxCodeSet.toArray()[0].toString();
      if (codePre.length() + numLenth.intValue() == maxCode.length()) {
        maxCode = maxCode.substring(codePre.length());
        inewIndex = Integer.valueOf(maxCode).intValue() + 1;
        iLen = ("" + inewIndex).length();
      } 
      for (int i = 0; i < numLenth.intValue() - iLen; i++)
        newCode.append("0"); 
      newCode.append(inewIndex);
    } 
    return newCode.toString();
  }
  
  private String getDepUserDefValue(String pk_org, String propIndex, String codePre) throws BusinessException {
    if (StringUtils.isEmpty(codePre))
      return null; 
    UserdefitemVO[] userdefitemVOs = ((IUserdefitemQryService)AMProxy.lookup(IUserdefitemQryService.class)).qeuryUserdefitemVOsByMDClassID("b26fa3cb-4087-4027-a3b6-c83ab2a086a9", pk_org);
    String classID = "";
    if (null != userdefitemVOs && userdefitemVOs.length > 0)
      for (UserdefitemVO tUserdefitemVO : userdefitemVOs) {
        Integer tPropIndex = tUserdefitemVO.getPropindex();
        if (null != tPropIndex && String.valueOf(tPropIndex).equals(propIndex)) {
          classID = tUserdefitemVO.getClassid();
          break;
        } 
      }  
    if (StringUtils.isNotEmpty(classID)) {
      IBean bean = MDBaseQueryFacade.getInstance().getBeanByID(classID);
      if (null == bean)
        return codePre; 
      Map<String, String> keyName = MultiLanguageUtil.getMultiLangByClassId(new String[] { codePre }, classID);
      if (null != keyName && keyName.keySet().size() > 0)
        return keyName.get(codePre); 
    } 
    return null;
  }
  
  public DepResultVO simulateAccDep(AssetVO vo) throws BusinessException {
    AssetSimulateDepFactory assetDepFactory = new AssetSimulateDepFactory();
    return assetDepFactory.proAccDep(vo);
  }
  
  public DepResultVO simulateDep(AssetVO assetVO) throws BusinessException {
    AssetSimulateDepFactory assetDepFactory = new AssetSimulateDepFactory();
    return assetDepFactory.procDep(assetVO);
  }
  
  public Map<String, String[]> queryNotWorkloanDepmethodFields(String[] pk_depmethods, boolean isClientCall) throws BusinessException {
    DepmethodVO[] methodVOs = (DepmethodVO[])QueryUtil.querySuperVOByPks(DepmethodVO.class, pk_depmethods);
    if (methodVOs == null || methodVOs.length == 0)
      ExceptionUtils.asBusinessException(NCLangRes4VoTransl.getNCLangRes().getStrByID("facard_0", "02012005-0416")); 
    String[] codes = BaseVOUtils.getVOAttributeNotNullValues((SuperVO[])methodVOs, "depmethod_code");
    if (Arrays.<String>asList(codes).contains("04"))
      return null; 
    Map<String, String[]> notWorkloan = (Map)new HashMap<>();
    for (int i = 0; i < methodVOs.length; i++) {
      String pk_deptmethod = methodVOs[i].getPk_depmethod();
      if (!methodVOs[i].getDepmethod_code().equals("04")) {
        if (methodVOs[i].getPre_flag().equals("0")) {
          Set<String> workloanFidles = new HashSet<>();
          String amountformula = methodVOs[i].getAmountexpression();
          String rate = methodVOs[i].getRateexpression();
          Set<String> fileNameSet = new HashSet<>();
          if (amountformula != null && amountformula.length() > 0) {
            FormulaParse parse = new FormulaParse();
            String[] fileNames = parse.getVarry(amountformula).getVarry();
            if (fileNames != null && fileNames.length > 0)
              fileNameSet.addAll(Arrays.asList(fileNames)); 
          } 
          if (rate != null && rate.length() > 0) {
            FormulaParse parse = new FormulaParse();
            String[] fileNames = parse.getVarry(rate).getVarry();
            if (fileNames != null && fileNames.length > 0)
              fileNameSet.addAll(Arrays.asList(fileNames)); 
          } 
          for (String workloanField : AssetUseConst.workLoadFields) {
            if (fileNameSet.contains(workloanField))
              workloanFidles.add(workloanField); 
          } 
          String[] tempArray = (String[])ArrayUtils.addElement(workloanFidles.toArray((Object[])new String[0]), (Object[])new String[] { "preFlag0" });
          notWorkloan.put(pk_deptmethod, tempArray);
        } 
        if (methodVOs[i].getPre_flag().equals("1") && 
          !isClientCall) {
          String[] tempArray = (String[])ArrayUtils.addElement((Object[])AssetUseConst.workLoadFields, (Object[])new String[] { "preFlag1" });
          notWorkloan.put(pk_deptmethod, tempArray);
        } 
      } 
    } 
    return notWorkloan;
  }
  
  public AggCardVO getAggCardVOWhenLast(String pk_card) throws BusinessException {
    CardVO[] cVOs = (CardVO[])QueryUtil.querySuperVOByPks(CardVO.class, new String[] { pk_card });
    if (cVOs == null || cVOs.length == 0)
      return null; 
    String whereSql = "pk_card = '" + pk_card + "' and " + AssetStateConst.getNewestAssetSql(true);
    CardhistoryVO[] queryHis = (CardhistoryVO[])QueryUtil.queryVOByCond(CardhistoryVO.class, whereSql, null);
    if (queryHis == null || queryHis.length == 0)
      return null; 
    AggCardVO aggvo = new AggCardVO();
    aggvo.setParentVO((CircularlyAccessibleValueObject)cVOs[0]);
    aggvo.setTableVO(CardTabConst.history, (CircularlyAccessibleValueObject[])queryHis);
    AssetScaleProcessUtil.scaleProcess((AggregatedValueObject[])new AggCardVO[] { aggvo });
    return aggvo;
  }
  
  public AggCardVO getAggCardVOWhenAdd(String pk_card) throws BusinessException {
    CardVO[] cVOs = (CardVO[])QueryUtil.querySuperVOByPks(CardVO.class, new String[] { pk_card });
    if (cVOs == null || cVOs.length == 0)
      return null; 
    StringBuilder wherSql = new StringBuilder();
    wherSql.append("pk_card = '" + pk_card + "'");
    wherSql.append(" and laststate_flag = '" + UFBoolean.FALSE + "'");
    wherSql.append(" and newasset_flag < 2");
    CardhistoryVO[] queryHis = (CardhistoryVO[])QueryUtil.queryVOByCond(CardhistoryVO.class, wherSql.toString(), null);
    if (queryHis == null || queryHis.length == 0)
      return null; 
    List<CardhistoryVO> allHisVOs = new ArrayList<>();
    for (int i = 0; i < queryHis.length; i++) {
      CardhistoryVO newVO = (CardhistoryVO)CloneUtil.clone(queryHis[i]);
      newVO.setLaststate_flag(UFBoolean.TRUE);
      allHisVOs.add(queryHis[i]);
      allHisVOs.add(newVO);
    } 
    AggCardVO aggvo = new AggCardVO();
    aggvo.setParentVO((CircularlyAccessibleValueObject)cVOs[0]);
    aggvo.setTableVO(CardTabConst.history, (CircularlyAccessibleValueObject[])CollectionUtils.toArray(allHisVOs));
    AssetScaleProcessUtil.scaleProcess((AggregatedValueObject[])new AggCardVO[] { aggvo });
    return aggvo;
  }
  
  public AggAssetVO[] queryAboutByBudgetControl(Object paramVO) throws BusinessException {
    if (!NtbParamTool.isNtbParamVO(paramVO))
      return null; 
    NtbParamTool paramTool = new NtbParamTool(paramVO);
    boolean hasUsedept = paramTool.hasControlAttr("pk_usedept");
    Map<String, String> fileColumnName = new HashMap<>();
    fileColumnName.put("pk_org", "h.pk_org");
    fileColumnName.put("business_date", "c.business_date");
    fileColumnName.put("pk_category", "h.pk_category");
    fileColumnName.put("pk_mandept", "h.pk_mandept");
    if (hasUsedept)
      fileColumnName.put("pk_usedept", "u.pk_dept"); 
    StringBuffer sql = new StringBuffer();
    sql.append("select pk_cardhistory ");
    sql.append(" from fa_cardhistory h");
    sql.append(" inner join fa_card c on c.pk_card = h.pk_card");
    sql.append(" inner join fa_cardsub on fa_cardsub.pk_card = c.pk_card");
    sql.append(" and c.dr = 0");
    sql.append(" and c.bill_source = 'HN'");
    sql.append(" and h.business_flag = '" + UFBoolean.TRUE + "'");
    sql.append(" and h.laststate_flag = '" + UFBoolean.FALSE + "'");
    sql.append(" and h.newasset_flag < 2");
    if (hasUsedept)
      sql.append(" inner join fa_deptscale u on u.link_key = h.pk_usedept"); 
    sql.append(" and " + paramTool.getCardQueryWhereSql(fileColumnName));
    List result = (List)this.dbUtil.executeQuery(sql.toString(), (ResultSetProcessor)new ArrayListProcessor());
    if (result != null && result.size() > 0) {
      String[] pk_cardhistorys = new String[result.size()];
      for (int i = 0; i < result.size(); i++)
        pk_cardhistorys[i] = ((Object[])result.get(i))[0].toString(); 
      AggAssetVO[] aggVOs = queryAggAssetVOByHistory(pk_cardhistorys);
      return aggVOs;
    } 
    return null;
  }
  
  public Map<String, String> rollBackAndGetPreBillCode(Map<String, String> nbcrcode_codes, String pk_group, String pk_org_old, String pk_org) throws BusinessException {
    if (StringUtils.isNotEmpty(pk_org_old))
      for (String nbcrcode : nbcrcode_codes.keySet()) {
        String oldCode = nbcrcode_codes.get(nbcrcode);
        if (StringUtils.isNotEmpty(oldCode))
          ((IBillCodeManageService)AMProxy.lookup(IBillCodeManageService.class)).rollBackPreBillCode(nbcrcode, pk_group, pk_org_old, oldCode); 
      }  
    Map<String, String> newCode = getPreBillCode((String[])CollectionUtils.toArray(nbcrcode_codes.keySet()), pk_group, pk_org);
    return newCode;
  }
  
  public Map<String, String> getPreBillCode(String[] nbcrcodes, String pk_group, String pk_org) throws BusinessException {
    Map<String, String> newCodes = new HashMap<>();
    if (ArrayUtils.isNotEmpty((Object[])nbcrcodes))
      for (String nbcrcode : nbcrcodes) {
        String code = getPreBillCode(nbcrcode, pk_group, pk_org);
        if (StringUtils.isNotEmpty(code))
          newCodes.put(nbcrcode, code); 
      }  
    return newCodes;
  }
  
  private String getPreBillCode(String nbcrcode, String pk_group, String pk_org) throws BusinessException {
    String field = "card_code";
    BillCodeContext newCodeContext = ((IBillcodeManage)AMProxy.lookup(IBillcodeManage.class)).getBillCodeContext(nbcrcode, pk_group, pk_org);
    if (newCodeContext != null) {
      if (newCodeContext.isPrecode()) {
        int i = 0;
        while (true) {
          String code = ((IBillCodeManageService)AMProxy.lookup(IBillCodeManageService.class)).getPreBillCode(nbcrcode, pk_group, pk_org);
          if (nbcrcode.equals("asset_code"))
            field = "asset_code"; 
          boolean hasThisCode = false;
          if (null != nbcrcode && !nbcrcode.equals("card_code"))
            hasThisCode = haveCodeCheck(code, field, newCodeContext.getUniquescope(), pk_org); 
          if (!hasThisCode)
            return code; 
          i++;
          if (i > 5) {
            IBean cardBean = MDBaseQueryFacade.getInstance().getBeanByFullClassName(CardVO.class.getName());
            String errorFieldName = cardBean.getAttributeByName(field).getDisplayName();
            ExceptionUtils.asBusinessException(errorFieldName + 
                NCLangRes4VoTransl.getNCLangRes().getStrByID("facard_0", "02012005-0417"));
          } 
        } 
      } 
      return AssetUseConst.codeisNotProCode;
    } 
    return AssetUseConst.codeisNull;
  }
  
  private boolean haveCodeCheck(String code, String field, String uniquescope, String pk_org) throws BusinessException {
    String pk_group = InvocationInfoProxy.getInstance().getGroupId();
    StringBuffer sql = new StringBuffer();
    sql.append("select");
    sql.append(" count(pk_card)");
    sql.append(" from fa_card");
    sql.append(" where ");
    sql.append(field + " = '" + code + "'");
    if (uniquescope.equals("g")) {
      sql.append(" and pk_group = '" + pk_group + "'");
    } else if (uniquescope.equals("o")) {
      sql.append(" and pk_org = '" + pk_org + "'");
    } 
    sql.append(" and dr = 0");
    int lenth = ((Integer)this.dbUtil.executeQuery(sql.toString(), (ResultSetProcessor)new CountProcessor())).intValue();
    if (lenth > 0)
      return true; 
    return false;
  }
  
  public RelativeDataVO doDefaultRelative(AggAssetVO aggAvo) throws BusinessException {
    AssetEntiretyVO evo = CardVOUtils.getAssetEntiretyVOFromAggVO(aggAvo);
    RelativeActionManager rm = RelativeFactory.getDefaultRelativeManager();
    ClientRelateHandler handler = new ClientRelateHandler(evo);
    rm.setHandler((IRelateHandler)handler);
    RelateEventObject eventOrg = RelativeTool.createRelateClientEvent((IRelateHandler)handler, "pk_org");
    rm.doAction("pk_org", eventOrg);
    String sourceType = evo.getCardVO().getBill_source();
    if (!sourceType.equals("handin")) {
      RelateEventObject eventCategory = RelativeTool.createRelateClientEvent((IRelateHandler)handler, "pk_category");
      rm.doAction("pk_category", eventCategory);
    } 
    RelateEventObject eventBsValue = RelativeTool.createRelateClientEvent((IRelateHandler)handler, "business_date");
    rm.doAction("business_date", eventBsValue);
    RelateEventObject eventOriginValue = RelativeTool.createRelateClientEvent((IRelateHandler)handler, "originvalue");
    rm.doAction("originvalue", eventOriginValue);
    RelateEventObject usedeptValue = RelativeTool.createRelateClientEvent((IRelateHandler)handler, "pk_usedept");
    rm.doAction("pk_usedept", usedeptValue);
    RelateEventObject depMethodValue = RelativeTool.createRelateClientEvent((IRelateHandler)handler, "pk_depmethod");
    rm.doAction("pk_depmethod", depMethodValue);
    rm.doSourceBillPro(aggAvo);
    return handler.getRelativeDataVO();
  }
  
  public RelativeDataVO doEditRelative(AssetEntiretyVO evo, String acitonCode, String pk_accbook, UFBoolean fromAccbookChange) throws BusinessException {
    RelativeActionManager rm = RelativeFactory.getDefaultRelativeManager();
    ClientRelateHandler handler = new ClientRelateHandler(evo);
    rm.setHandler((IRelateHandler)handler);
    handler.setSelectedAccbook(pk_accbook);
    RelateEventObject eventOrg = RelativeTool.createRelateClientEvent((IRelateHandler)handler, acitonCode);
    eventOrg.setAccbookChange(fromAccbookChange.booleanValue());
    rm.doAction(acitonCode, eventOrg);
    return handler.getRelativeDataVO();
  }
  
  public AggAssetVO[] queryAggVOHaveChildByCardhistory(String[] pk_cardhistorys) throws BusinessException {
    AggAssetVO[] aggAvos = queryAggAssetVOByHistory(pk_cardhistorys);
    fillBodyVOs(aggAvos);
    return aggAvos;
  }
  
  public AggAssetVO[] queryAggVONotChildByCardhistory(String[] pk_cardhistorys) throws BusinessException {
    AggAssetVO[] aggAvos = queryAggAssetVOByHistory(pk_cardhistorys);
    return aggAvos;
  }
  
  public AggAssetVO[] queryAggVONotChildByCardhistorySplitUsedept(String[] pk_cardhistorys) throws BusinessException {
    if (ArrayUtils.isEmpty((Object[])pk_cardhistorys))
      return null; 
    String whereSqlNew = "pk_cardhistory in" + InSqlManager.getInSQLValue(pk_cardhistorys);
    AssetVO[] vos = queryAssetVOBySQL(whereSqlNew);
    if (ArrayUtils.isEmpty((Object[])vos))
      ExceptionUtils.asBusinessException(NCLangRes4VoTransl.getNCLangRes().getStrByID("facard_0", "02012005-0412")); 
    Map<String, AssetVO[]> splitDatas = UseDeptScaleUtils.splitData("pk_usedept", null, vos);
    List<AggAssetVO> aggAvoList = new ArrayList<>();
    if (splitDatas != null && splitDatas.size() > 0)
      for (String key : splitDatas.keySet()) {
        AssetVO[] splitData = splitDatas.get(key);
        if (ArrayUtils.isNotEmpty((Object[])splitData))
          for (AssetVO vo : splitData) {
            AggAssetVO aggAvo = new AggAssetVO();
            aggAvo.setParentVO((CircularlyAccessibleValueObject)vo);
            aggAvoList.add(aggAvo);
          }  
      }  
    return (AggAssetVO[])CollectionUtils.toArray(aggAvoList);
  }
  
  public CategoryVO queryCategoryVOByEquipCategory(String pk_category_equip, LoginContext context) throws BusinessException {
    Map<String, String> categoryData = ((ICategoryFaService)AMProxy.lookup(ICategoryFaService.class)).queryEquipAndAssetCategory(new String[] { pk_category_equip }, context);
    if (categoryData == null || categoryData.size() == 0)
      return null; 
    String pk_category = categoryData.get(pk_category_equip);
    String msg = ((ICategoryService)AMProxy.lookup(ICategoryService.class)).isSealOrEnd(pk_category, context.getPk_org());
    if (StringUtils.isNotEmpty(msg)) {
      if (msg.indexOf(NCLangRes4VoTransl.getNCLangRes().getStrByID("deploy_0", "02012020-0052")) > -1)
        return null; 
      if (msg.indexOf(NCLangRes4VoTransl.getNCLangRes().getStrByID("deploy_0", "02012020-0053")) > -1)
        return null; 
      ExceptionUtils.asBusinessException(msg);
    } 
    CategoryVO vo = ((ICategoryService)AMProxy.lookup(ICategoryService.class)).queryCategoryByPK(pk_category);
    return vo;
  }
  
  public int queryDailyCardOrgNum(String pk_group, String pk_org, String pk_depmethod) throws BusinessException {
    String sql = "select count(a.allRow) from (select count(distinct pk_org) allRow from fa_cardhistory where pk_depmethod = ? and dr = 0 group by pk_org) a";
    SQLParameter sp = new SQLParameter();
    sp.addParam(pk_depmethod);
    Object num = (new DBAccessUtil()).executeQuery(sql, sp, (ResultSetProcessor)new CountProcessor());
    return Integer.parseInt(num.toString());
  }
  
  public boolean faMutiAccbookCount(String pk_group, String pk_org) throws BusinessException {
    boolean canUsed = false;
    String sql = "select distinct pk_org from fa_cardhistory where pk_group = '" + pk_group + "' and dr = 0 \tgroup by pk_org having count(distinct pk_accbook) > 1";
    String sql1 = "select distinct pk_org from fa_cardhistory where pk_group = '" + pk_group + "' and newasset_flag in(0,1) and business_flag = 'N' and dr = 0";
    boolean cn = ((IAccountingBookPubService)AMProxy.lookup(IAccountingBookPubService.class)).isAssetBookOrgExceeded();
    boolean isMore = cn;
    if (!isMore)
      return true; 
    Set<String> usedAccbooks = (Set<String>)this.dbUtil.executeQuery(sql1, (ResultSetProcessor)new ColumnSetProcessor(1));
    canUsed = ((isMore && !usedAccbooks.contains(pk_org)) || usedAccbooks.contains(pk_org));
    return canUsed;
  }
  
  public Map<String, String> queryAccountInfo() throws BusinessException {
    Map<String, String> accountInfo = new HashMap<>();
    int multiSeq = MultiLanguageUtil.getMultiNameSeq();
    String currName = "name";
    if (multiSeq > 1)
      currName = currName + multiSeq; 
    String sql = "select pk_accasoa,code from bd_accasoa inner join bd_account on bd_accasoa.pk_account = bd_account.pk_account where bd_accasoa.dr = 0";
    accountInfo = (Map<String, String>)this.dbUtil.executeQuery(sql, (ResultSetProcessor)new KeyValueMapProcessor("pk_accasoa", "code"));
    return accountInfo;
  }
  
  public Map<String, String> queryAlterPosition(List<String> pk_cards, String[] dates) {
    Map<String, String> measureValueMap = null;
    String sql = "select pk_card pk_card ,(business_date || '=' || old_content) old_content  from fa_alter inner join fa_alter_b on fa_alter.pk_alter = fa_alter_b.pk_alter inner join fa_altersheet on fa_alter.pk_alter = fa_altersheet.pk_alter where fa_altersheet.item_code = 'position' and fa_alter.bill_status = 3  and fa_alter.dr = 0 and fa_alter_b.dr = 0 and fa_altersheet.dr = 0 order by fa_alter.business_date desc";
    try {
      measureValueMap = (Map<String, String>)(new DBAccessUtil()).executeQuery(sql, (ResultSetProcessor)new KeyValueMapProcessor("pk_card", "old_content"));
    } catch (DAOException e) {
      Logger.debug("查询卡片做存放地点异常"+ e.getMessage());
    } 
    return measureValueMap;
  }
}
