package nccloud.api.impl.mmbd.bom;


import nc.bs.dao.BaseDAO;
import nc.bs.framework.common.InvocationInfoProxy;
import nc.bs.framework.common.NCLocator;
import nc.itf.bd.bom.bom0202.IBomBillMaintainService;
import nc.itf.bd.bom.bom0202.IBomBillQueryService;
import nc.itf.mmf.busi.measure.IMeasesureService;
import nc.itf.uif.pub.IUifService;
import nc.jdbc.framework.SQLParameter;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.mmbd.utils.factoryparam.MMBDFactoryParameter;
import nc.pubitf.uapbd.IMaterialPubService;
import nc.pubitf.uapbd.IMaterialPubService_C;
import nc.ui.querytemplate.querytree.IQueryScheme;
import nc.util.bd.bom.openapi.BillFieldsCodeToPkUtil;
import nc.util.mmf.busi.measure.MeasureHelper;
import nc.util.mmf.busi.measure.MeasureParam;
import nc.util.mmf.busi.measure.MeasureVO;
import nc.util.mmf.busi.measure.NumScaleUtil;
import nc.util.mmf.busi.service.OrgUnitPubService;
import nc.util.mmf.framework.base.MMValueCheck;
import nc.vo.bd.bom.bom0202.entity.*;
import nc.vo.bd.bom.bom0202.enumeration.*;
import nc.vo.bd.bom.bom0202.paramvo.BomHeadMtrlParam;
import nc.vo.bd.bom.bom0202.paramvo.BomHeadMtrlResult;
import nc.vo.bd.bom.bom0202.paramvo.BomMaterialParam;
import nc.vo.bd.material.MaterialVO;
import nc.vo.bd.material.MaterialVersionVO;
import nc.vo.bd.material.plan.MaterialPlanVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.CircularlyAccessibleValueObject;
import nc.vo.pub.ISuperVO;
import nc.vo.pub.SuperVO;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pub.lang.UFDate;
import nc.vo.pub.lang.UFDateTime;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pubapp.AppContext;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nc.vo.pubapp.pattern.model.entity.bill.AbstractBill;
import nccloud.api.mmbd.bom.IAPIBomBusinessService;
import nccloud.api.mmbd.utils.QuerySchemeUtils;
import nccloud.api.rest.utils.ResultMessageUtil;
import nccloud.pubift.commen.itf.utils.IHttpPostOtherSys;
import nccloud.vo.bd.bom.bom0202.validate.BomSavingValidation;
import org.json.JSONString;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class APIBomBusinessServiceImpl implements IAPIBomBusinessService {

	// 2025年5月28日 电缆组织金思维BOM版本号自动计算处理
    private static final BaseDAO DAO = new BaseDAO();
    
    private static final IHttpPostOtherSys HTTP_POST_OTHER_SYS = NCLocator.getInstance().lookup(IHttpPostOtherSys.class);

	public static final String MESUSERCODE = "MES";

	private static String HEADTABLE = "bd_bom";

	private static String BODYTABLE = "bd_bom_b";

	private static String ORGTABLE = "bd_bom_useorg";

	private static String ACTIVITYTABLE = "bd_bom_activity";

	private static String OUTPUTSTABLE = "bd_bom_outputs";

	private static String POSITIONTABLE = "bd_bom_position";

	private static String REPLTABLE = "bd_bom_repl";

	private static String LOSSTABLE = "bd_bom_loss";

	private static String WIPTABLE = "bd_bom_wip";

	private static Map<String, Object> tsMap = new HashMap();

	private String orgCodeFlag =null;

	private static Map<String, Object> voMap = new HashMap();

	private static Map<String, Set<String>> idsMap = new HashMap();

	public JSONString insert(List<Map<String, Object>> paramList) {
		try {
			IBomBillMaintainService service = (IBomBillMaintainService) NCLocator.getInstance()
					.lookup(IBomBillMaintainService.class);
			List<AggBomVO> list = new ArrayList<AggBomVO>();
			for (Map<String, Object> paramMap : paramList) {
				if (!paramMap.containsKey(HEADTABLE) || !paramMap.containsKey(BODYTABLE)) {
					return ResultMessageUtil.exceptionToJSON("传入数据异常，参数要包含表头信息和表体信息", "1");
				}

				AggBomVO agg = aggInit(paramMap);

				JSONString checkInfo = requiredCheck(agg);
				if (checkInfo != null) {
					return checkInfo;
				}

				list.add(agg);
			}
			AggBomVO[] aggVOs = (AggBomVO[]) list.toArray(new AggBomVO[list.size()]);
			if(aggVOs[0].getParentVO().getAttributeValue("pk_org")==null||aggVOs[0].getParentVO().getAttributeValue("pk_org")==""){
				ExceptionUtils.wrappBusinessException("请求参数pk_org为空，请检查！！！！");
			}else{
				this.orgCodeFlag=aggVOs[0].getParentVO().getAttributeValue("pk_org").toString();
			}
			BillFieldsCodeToPkUtil.doTranslateVOFields(aggVOs);
			IUifService iUifService = NCLocator.getInstance().lookup(IUifService.class);
			for (AggBomVO aggtwo : aggVOs) {
				BomItemVO[] items = aggtwo.getChildrenVO();
				//2025年5月9日08点56分--添加表头物料翻译校验	start
				if(aggtwo.getParent().getAttributeValue("hcmaterialid")!=null){
					MaterialVO headMaterialVO = (MaterialVO) iUifService.queryByPrimaryKey(MaterialVO.class,
							aggtwo.getParent().getAttributeValue("hcmaterialid").toString());
					if(headMaterialVO==null){
						ExceptionUtils.wrappBusinessException("根据物料【"+aggtwo.getParent().getAttributeValue("hcmaterialid").toString()+"】查询物料失败，请在BIP里确认是否物料已存在！！！");
					}
				}
				//2025年5月9日08点56分--添加表头物料翻译校验 end
				for (int i = 0; i < items.length; i++) {
					MaterialVO bankAccSub = (MaterialVO) iUifService.queryByPrimaryKey(MaterialVO.class,
							items[i].getAttributeValue("cmaterialid").toString());
					//2025年5月7日08点41分 添加为空校验 sdlizheng --start
					if(bankAccSub==null){
						ExceptionUtils.wrappBusinessException("根据物料【"+items[i].getAttributeValue("cmaterialid").toString()+"】查询物料失败，请在BIP里确认是否物料已存在！！！");
					}
					//2025年5月7日08点41分 添加为空校验 sdlizheng --end
					items[i].setAttributeValue("cmaterialvid", bankAccSub.getAttributeValue("pk_source"));
				}
			}
			List<AggBomVO> commitAggvoList = new ArrayList<>();
			List<AggBomVO> addAggvoList = new ArrayList<>();
			String userCode = InvocationInfoProxy.getInstance().getUserCode();
			for (AggBomVO agg : aggVOs) {
				Object fBillStatusFlag = agg.getParent().getAttributeValue("fbillstatus");
				if (fBillStatusFlag == null || "-1".equals(fBillStatusFlag.toString())) {
					addAggvoList.add(agg);
				} else if ("1".equals(fBillStatusFlag.toString())) {
					commitAggvoList.add(agg);
				}
				// zhangxinah 对物料主键进行翻译
				dealWithMaterial(agg);

				// 2025年5月28日 电缆组织金思维BOM版本号自动计算处理 By maolei
				handleCableOrgJinSiWeiBomVersion(agg);

				dataSupplement(agg, userCode);

				UFBoolean flag = (UFBoolean) agg.getParent().getAttributeValue("hbdefault");
				if (UFBoolean.TRUE.equals(flag)) {
					UFBoolean bHasOtherDefaultVersion = getIsExistDefaultVersion(agg, userCode);
					if (bHasOtherDefaultVersion.equals(UFBoolean.TRUE)) {
						ExceptionUtils.wrappBusinessException("有其它默认版本，请检查！！！");
					}
				}
				(new BomSavingValidation()).validate(agg);
			}

			mapClear();
			// 请求参数状态为审批通过时，自动提交--不设审批流 start
			AggBomVO[] result = null;
			if (commitAggvoList.isEmpty() && addAggvoList.isEmpty()) {
				return ResultMessageUtil.exceptionToJSON("BOM保存失败,不存在单据状态不为【空/自由/审批通过】的数据", "999");
			} else if (commitAggvoList.isEmpty() && !addAggvoList.isEmpty()) {
				result = service.insertBom((AggBomVO[]) addAggvoList.toArray(new AggBomVO[0]));
			} else if (!commitAggvoList.isEmpty() && addAggvoList.isEmpty()) {
				List<AggBomVO> newAggVOList = new ArrayList<>();
				if ("gaoning".equals(userCode)|| "C029".equals(orgCodeFlag)) {
					for (AggBomVO aggvo : commitAggvoList) {
						result = service.insertCommitBomWithParam(new AggBomVO[] { aggvo }, true, true);
						newAggVOList.add(result[0]);
					}
					return ResultMessageUtil.toJSON(newAggVOList.toArray(new AggBomVO[0]), "BOM保存成功");
				} else if ("dlkgsrm".equals(userCode)) {
					for (AggBomVO aggvo : commitAggvoList) {
						try {
							result = service.insertCommitBomWithParam_RequiresNew(new AggBomVO[] { aggvo }, true, true);
							newAggVOList.add(result[0]);
						} catch (Exception e) {
							if (e.getMessage() != null) {
								if (e.getMessage().length() > 100) {
									aggvo.getParent().setAttributeValue("hvdef2", e.getMessage().substring(0, 100));
								} else {
									aggvo.getParent().setAttributeValue("hvdef2",
											e.getMessage().substring(0, e.getMessage().length() - 1));
								}
							} else {
								Throwable unmarsh = ExceptionUtils.unmarsh(e);
								aggvo.getParent().setAttributeValue("hvdef2", "异常" + unmarsh.getMessage());
							}

							newAggVOList.add(aggvo);
						}
					}
					return ResultMessageUtil.toJSON(newAggVOList.toArray(new AggBomVO[0]), "100999",
							"BOM保存提交成功部分成功部分失败", true);
				} else {
					try {
						IHttpPostOtherSys httpPostOtherSys = NCLocator.getInstance().lookup(IHttpPostOtherSys.class);
						
						// 检查当前用户是否为排除用户
						if (httpPostOtherSys.checkIfExcludeUser()) {
							// 排除用户直接跳过同步处理，执行普通保存逻辑
							for (AggBomVO aggvo : commitAggvoList) {
								result = service.insertBom(new AggBomVO[] { aggvo });
								newAggVOList.add(result[0]);
							}
							return ResultMessageUtil.toJSON(newAggVOList.toArray(new AggBomVO[0]), "BOM保存成功(排除用户)");
						}
						
						// 检查当前组织是否属于金思维MES同步组织(电缆组织)
						String currentOrgCode = this.orgCodeFlag;
						boolean isIncludeOrg = httpPostOtherSys.checkIfIncludeOrg(currentOrgCode);
						
						if (isIncludeOrg) {
							// 属于金思维MES同步组织，执行特殊处理逻辑
							for (AggBomVO aggvo : commitAggvoList) {
								result = service.insertCommitBomWithParam(new AggBomVO[] { aggvo }, true, true);
								newAggVOList.add(result[0]);
							}
							return ResultMessageUtil.toJSON(newAggVOList.toArray(new AggBomVO[0]), "BOM保存成功(金思维MES同步组织)");
						} else {
							// 不属于金思维MES同步组织，执行默认处理逻辑
							for (AggBomVO aggvo : commitAggvoList) {
								try {
									result = service.insertCommitBomWithParam_RequiresNew(new AggBomVO[] { aggvo }, true, true);
									newAggVOList.add(result[0]);
								} catch (Exception e) {
									if (e.getMessage() != null) {
										if (e.getMessage().length() > 100) {
											aggvo.getParent().setAttributeValue("hvdef2", e.getMessage().substring(0, 100));
										} else {
											aggvo.getParent().setAttributeValue("hvdef2",
													e.getMessage().substring(0, e.getMessage().length() - 1));
										}
									} else {
										Throwable unmarsh = ExceptionUtils.unmarsh(e);
										aggvo.getParent().setAttributeValue("hvdef2", "异常" + unmarsh.getMessage());
									}
									newAggVOList.add(aggvo);
								}
							}
							return ResultMessageUtil.toJSON(newAggVOList.toArray(new AggBomVO[0]), "100999",
									"BOM保存提交成功部分成功部分失败", true);
						}
					} catch (BusinessException e) {
						// HTTP工具类调用失败时，回退到原有的异常处理
						ExceptionUtils.wrappBusinessException("HTTP工具类判断失败：" + e.getMessage() + "，未匹配到符合条件的三方注册用户账号【"+userCode+"】，请检查！！！");
					}
				}
				
			} else {
				return ResultMessageUtil.exceptionToJSON("BOM保存失败,新增不允许单据状态自由或者空和审批通过同时存在", "999");
			}
			// 请求参数状态为审批通过时，自动提交--不设审批流 end
			return ResultMessageUtil.toJSON(result, "BOM保存成功");
		} catch (Exception e) {
			return ResultMessageUtil.exceptionToJSON(e);
		}
	}

	private void dealWithMaterial(AggBomVO agg) {
		String hcmaterialvid = (String) agg.getParentVO().getAttributeValue("hcmaterialvid");
		String hcmaterialid = (String) agg.getParentVO().getAttributeValue("hcmaterialid");
		// 物料没启用版本，直接赋值
		if (hcmaterialvid.length() == 20) {
			agg.getParentVO().setAttributeValue("hcmaterialid", hcmaterialvid);
		}
		// 物料没启用版本，直接赋值
		if (hcmaterialid.length() == 20) {
			agg.getParentVO().setAttributeValue("hcmaterialvid", hcmaterialid);
		}
	}

	public JSONString update(List<Map<String, Object>> paramList) {
		try {
			IBomBillMaintainService service = (IBomBillMaintainService) NCLocator.getInstance()
					.lookup(IBomBillMaintainService.class);

			IBomBillQueryService queryService = (IBomBillQueryService) NCLocator.getInstance()
					.lookup(IBomBillQueryService.class);
			List<AggBomVO> list = new ArrayList<AggBomVO>();
			List<String> idList = new ArrayList<String>();
			Map<String, AggBomVO> map = new HashMap<String, AggBomVO>();
			for (Map<String, Object> paramMap : paramList) {

				Map<String, Object> bom = (Map) paramMap.get(HEADTABLE);
				idList.add((String) bom.get("cbomid"));
			}
			AggBomVO[] originalvos = queryService.queryAggBomByBomID((String[]) idList.toArray(new String[0]));
			for (AggBomVO originalvo : originalvos) {
				map.put(originalvo.getParent().getPrimaryKey(), originalvo);
			}

			for (Map<String, Object> paramMap : paramList) {
				if (!paramMap.containsKey(HEADTABLE) || !paramMap.containsKey(BODYTABLE)) {
					return ResultMessageUtil.exceptionToJSON("传入数据异常，参数要包含表头信息和表体信息", "1");
				}

				Map<String, Object> bom = (Map) paramMap.get(HEADTABLE);
				AggBomVO original = (AggBomVO) map.get((String) bom.get("cbomid"));

				mapInit(original);

				AggBomVO agg = aggInit(paramMap);
				// 2025年4月11日14点35分 --重新赋值上制单人创建人+默认 --start
				agg.getParentVO().setAttributeValue("billmaker", original.getParent().getAttributeValue("billmaker"));
				agg.getParentVO().setAttributeValue("creator", original.getParent().getAttributeValue("creator"));
				if (bom.get("hbdefault") == null) {
					agg.getParentVO().setAttributeValue("hbdefault",
							original.getParent().getAttributeValue("hbdefault"));
				}
				// 2025年4月11日14点35分 --重新赋值上制单人创建人+默认 --end
				JSONString checkInfo = requiredCheck(agg);
				if (checkInfo != null) {
					return checkInfo;
				}
				list.add(agg);
			}

			AggBomVO[] aggVOs = (AggBomVO[]) list.toArray(new AggBomVO[list.size()]);

			BillFieldsCodeToPkUtil.doTranslateVOFields(aggVOs);
			IUifService iUifService = NCLocator.getInstance().lookup(IUifService.class);
			for (AggBomVO aggtwo : aggVOs) {
				//2025年5月9日08点56分--添加表头物料翻译校验	start
				if(aggtwo.getParent().getAttributeValue("hcmaterialid")!=null){
					MaterialVO headMaterialVO = (MaterialVO) iUifService.queryByPrimaryKey(MaterialVO.class,
							aggtwo.getParent().getAttributeValue("hcmaterialid").toString());
					if(headMaterialVO==null){
						ExceptionUtils.wrappBusinessException("根据物料【"+aggtwo.getParent().getAttributeValue("hcmaterialid").toString()+"】查询物料失败，请在BIP里确认是否物料已存在！！！");
					}
				}
				//2025年5月9日08点56分--添加表头物料翻译校验 end
				BomItemVO[] items = aggtwo.getChildrenVO();
				for (int i = 0; i < items.length; i++) {
					MaterialVO bankAccSub = (MaterialVO) iUifService.queryByPrimaryKey(MaterialVO.class,
							items[i].getAttributeValue("cmaterialid").toString());
					//2025年5月7日08点41分 添加为空校验 sdlizheng --start
					if(bankAccSub==null){
						ExceptionUtils.wrappBusinessException("根据物料【"+items[i].getAttributeValue("cmaterialid").toString()+"】查询物料失败，请在BIP里确认是否物料已存在！！！");
					}
					//2025年5月7日08点41分 添加为空校验 sdlizheng --end
					items[i].setAttributeValue("cmaterialvid", bankAccSub.getAttributeValue("pk_source"));
				}
			}
			String userCode = InvocationInfoProxy.getInstance().getUserCode();
			for (AggBomVO agg : aggVOs) {
				// zhangxinah 对物料主键进行翻译
				dealWithMaterial(agg);
				dataSupplement(agg, userCode);

				UFBoolean flag = (UFBoolean) agg.getParent().getAttributeValue("hbdefault");
				if (UFBoolean.TRUE.equals(flag)) {
					UFBoolean bHasOtherDefaultVersion = getIsExistDefaultVersion(agg, userCode);
					if (bHasOtherDefaultVersion.equals(UFBoolean.TRUE)) {
						ExceptionUtils.wrappBusinessException("有其它默认版本，请检查！！！");
					}
				}

				(new BomSavingValidation()).validate(agg);
			}

			mapClear();

			AggBomVO[] result = service.updateBom((AggBomVO[]) list.toArray(new AggBomVO[0]));
			return ResultMessageUtil.toJSON(result, "BOM保存成功");
		} catch (Exception e) {
			return ResultMessageUtil.exceptionToJSON(e);
		}
	}

	public JSONString query(Map<String, Object> paramMap) {
		try {
			Map<String, Object> map = mapDataTranslator(paramMap);

			QuerySchemeUtils schemeUtil = new QuerySchemeUtils(AggBomVO.class, map);
			IQueryScheme queryscheme = schemeUtil.creatQueryScheme();
			IBomBillQueryService query = (IBomBillQueryService) NCLocator.getInstance()
					.lookup(IBomBillQueryService.class);

			AggBomVO[] aggvos = query.queryBySchemeAndPwdkeyForBomWithParam(queryscheme, null, getRelation(), false,
					false);

			if (MMValueCheck.isEmpty(aggvos)) {
				return ResultMessageUtil.toJSON(new AggBomVO[0], "无相应数据");
			}

			Set<String> pkSet = (Set) Stream.of(aggvos).map(AbstractBill::getPrimaryKey).collect(Collectors.toSet());
			AggBomVO[] results = query.queryAggBomByBomID((String[]) pkSet.toArray(new String[0]));

			List<BomVO> list = new ArrayList<BomVO>();
			if (MMValueCheck.isNotEmpty(aggvos)) {
				for (AggBomVO agg : aggvos) {
					list.add((BomVO) agg.getParentVO());
				}
			}
			return ResultMessageUtil.toJSON(results, "查询成功");
		} catch (Exception e) {
			return ResultMessageUtil.exceptionToJSON(e);
		}
	}

	private void mapInit(AggBomVO aggs) {
		tsMap.put(aggs.getParent().getPrimaryKey(), aggs.getParent().getAttributeValue("ts"));

		BomItemVO[] items = aggs.getChildrenVO();

		if (MMValueCheck.isEmpty(items)) {
			return;
		}

		Set<String> itemSet = new HashSet<String>();
		for (BomItemVO item : items) {
			tsMap.put(item.getPrimaryKey(), item.getTs());
			voMap.put(item.getPrimaryKey(), item);
			itemSet.add(item.getPrimaryKey());

			BomWipVO[] wips = item.getWips();
			Set<String> wipSet = new HashSet<String>();
			if (MMValueCheck.isNotEmpty(wips)) {
				for (BomWipVO vo : wips) {
					tsMap.put(vo.getCbom_wipid(), vo.getTs());
					voMap.put(vo.getCbom_wipid(), vo);
					wipSet.add(vo.getCbom_wipid());
				}
				idsMap.put(WIPTABLE, wipSet);
			}

			BomPosVO[] pos = item.getPos();
			Set<String> posSet = new HashSet<String>();
			if (MMValueCheck.isNotEmpty(pos)) {
				for (BomPosVO vo : pos) {
					tsMap.put(vo.getCbom_positionid(), vo.getTs());
					voMap.put(vo.getCbom_positionid(), vo);
					posSet.add(vo.getCbom_positionid());
				}
				idsMap.put(POSITIONTABLE, posSet);
			}

			BomLossVO[] loss = item.getLoss();
			Set<String> lossSet = new HashSet<String>();
			if (MMValueCheck.isNotEmpty(loss)) {
				for (BomLossVO vo : loss) {
					tsMap.put(vo.getCbom_lossid(), vo.getTs());
					voMap.put(vo.getCbom_lossid(), vo);
					lossSet.add(vo.getCbom_lossid());
				}
				idsMap.put(LOSSTABLE, lossSet);
			}

			BomReplVO[] repl = item.getRepl();
			Set<String> replSet = new HashSet<String>();
			if (MMValueCheck.isNotEmpty(repl)) {
				for (BomReplVO vo : repl) {
					tsMap.put(vo.getCbom_replaceid(), vo.getTs());
					voMap.put(vo.getCbom_replaceid(), vo);
					replSet.add(vo.getCbom_replaceid());
				}
				idsMap.put(REPLTABLE, replSet);
			}
		}

		idsMap.put(BODYTABLE, itemSet);

		BomActivityVO[] activityVOs = (BomActivityVO[]) aggs.getChildren(BomActivityVO.class);
		Set<String> activitySet = new HashSet<String>();
		if (MMValueCheck.isNotEmpty(activityVOs)) {
			for (BomActivityVO vo : activityVOs) {
				tsMap.put(vo.getCbom_activityid(), vo.getTs());
				voMap.put(vo.getCbom_activityid(), vo);
				activitySet.add(vo.getCbom_activityid());
			}
			idsMap.put(ACTIVITYTABLE, activitySet);
		}

		BomUseOrgVO[] useOrgVOs = (BomUseOrgVO[]) aggs.getChildren(BomUseOrgVO.class);
		Set<String> orgSet = new HashSet<String>();
		if (MMValueCheck.isNotEmpty(useOrgVOs)) {
			for (BomUseOrgVO vo : useOrgVOs) {
				tsMap.put(vo.getPk_bom_useorg(), vo.getTs());
				voMap.put(vo.getPk_bom_useorg(), vo);
				orgSet.add(vo.getPk_bom_useorg());
			}
			idsMap.put(ORGTABLE, orgSet);
		}

		BomOutputsVO[] outputVOs = (BomOutputsVO[]) aggs.getChildren(BomOutputsVO.class);
		Set<String> outputSet = new HashSet<String>();
		if (MMValueCheck.isNotEmpty(outputVOs)) {
			for (BomOutputsVO vo : outputVOs) {
				tsMap.put(vo.getCbom_outputsid(), vo.getTs());
				voMap.put(vo.getCbom_outputsid(), vo);
				outputSet.add(vo.getCbom_outputsid());
			}
			idsMap.put(OUTPUTSTABLE, outputSet);
		}
	}

	private void mapClear() {
		tsMap.clear();
		voMap.clear();
		idsMap.clear();
	}

	public Map<String, Object> mapDataTranslator(Map<String, Object> paramMap) {
		AggBomVO[] aggs = new AggBomVO[1];
		AggBomVO vo = new AggBomVO();

		BomVO head = new BomVO();
		for (String key : paramMap.keySet()) {
			head.setAttributeValue(key, paramMap.get(key));
		}
		vo.setParent(head);
		aggs[0] = vo;

		BillFieldsCodeToPkUtil.doTranslateVOFields(aggs);
		BomVO parent = (BomVO) aggs[0].getParent();
		Map<String, Object> map = new HashMap<String, Object>();
		for (String key : paramMap.keySet()) {
			map.put(key, parent.getAttributeValue(key));
		}
		return map;
	}

	private AggBomVO aggInit(Map<String, Object> paramMap) {
		AggBomVO vo = new AggBomVO();

		headInit(vo, paramMap);

		bodyInit(vo, paramMap);

		return vo;
	}

	private void headInit(AggBomVO vo, Map<String, Object> paramMap) {
		Map<String, Object> headInfo = (Map) paramMap.get(HEADTABLE);
		BomVO head = new BomVO();
		head.setPk_group(AppContext.getInstance().getPkGroup());
		for (String key : headInfo.keySet()) {
			head.setAttributeValue(key, headInfo.get(key));
		}

		head.setAttributeValue("vbilltype", "19B1");
		head.setAttributeValue("hfbomcategory", Integer.valueOf(BomCategoryEnum.NORMAL_BOM.toIntValue()));
		head.setAttributeValue("hbcustomized", UFBoolean.FALSE);
		head.setTs((UFDateTime) tsMap.get(head.getPrimaryKey()));
		vo.setParent(head);
	}

	private void bodyInit(AggBomVO vo, Map<String, Object> paramMap) {
		itemInit(vo, paramMap);

		useOrgInit(vo, paramMap);

		activityInit(vo, paramMap);

		outputsInit(vo, paramMap);
	}

	private void itemInit(AggBomVO agg, Map<String, Object> paramMap) {
		List<BomItemVO> list = new ArrayList<BomItemVO>();
		Set<String> set = (Set) idsMap.get(BODYTABLE);

		if (set == null) {
			set = new HashSet<String>();
		}

		List<Map<String, Object>> itemInfos = new ArrayList<Map<String, Object>>();

		if (paramMap.get(BODYTABLE) instanceof List) {
			itemInfos = (List) paramMap.get(BODYTABLE);
		} else {
			Map<String, Object> bodyInfo = (Map) paramMap.get(BODYTABLE);
			if (MMValueCheck.isNotEmpty(bodyInfo)) {
				itemInfos.add(bodyInfo);
			}
		}

		for (Map<String, Object> itemMap : itemInfos) {
			BomItemVO item = new BomItemVO();
			for (String key : itemMap.keySet()) {
				if (WIPTABLE.equals(key)) {
					List<Map<String, Object>> wipInfos = (List) itemMap.get(WIPTABLE);
					item.setWips(getWipVos(wipInfos));
				} else if (POSITIONTABLE.equals(key)) {
					List<Map<String, Object>> positionInfos = (List) itemMap.get(POSITIONTABLE);
					item.setPos(getPosVos(positionInfos));
				} else if (REPLTABLE.equals(key)) {
					List<Map<String, Object>> replInfos = (List) itemMap.get(REPLTABLE);
					item.setRepl(getReplVos(replInfos));
				} else if (LOSSTABLE.equals(key)) {
					List<Map<String, Object>> lossInfos = (List) itemMap.get(LOSSTABLE);
					item.setLoss(getLossVos(lossInfos, item));

				} else {

					item.setAttributeValue(key, itemMap.get(key));
				}
				if (MMValueCheck.isEmpty(item.getAttributeValue("cmaterialid")))
					;
			}

			set.remove(item.getPrimaryKey());
			item.setTs((UFDateTime) tsMap.get(item.getPrimaryKey()));
			if (MMValueCheck.isNotEmpty(item.getPrimaryKey())) {
				item.setStatus(1);
			} else {
				item.setStatus(2);
			}
			list.add(item);
		}

		for (String key : set) {
			BomItemVO vo = (BomItemVO) voMap.get(key);
			vo.setStatus(3);
			list.add(vo);
		}

		agg.setChildren(BomItemVO.class, (ISuperVO[]) list.toArray(new BomItemVO[0]));
	}

	private void useOrgInit(AggBomVO agg, Map<String, Object> paramMap) {
		List<BomUseOrgVO> list = new ArrayList<BomUseOrgVO>();
		Set<String> set = (Set) idsMap.get(ORGTABLE);

		if (set == null) {
			set = new HashSet<String>();
		}

		List<Map<String, Object>> orgInfos = new ArrayList<Map<String, Object>>();
		if (paramMap.get(ORGTABLE) instanceof List) {
			orgInfos = (List) paramMap.get(ORGTABLE);
		} else {
			Map<String, Object> orgInfo = (Map) paramMap.get(ORGTABLE);
			if (MMValueCheck.isNotEmpty(orgInfo)) {
				orgInfos.add(orgInfo);
			}
		}

		for (Map<String, Object> itemMap : orgInfos) {
			BomUseOrgVO item = new BomUseOrgVO();
			for (String key : itemMap.keySet()) {
				item.setAttributeValue(key, itemMap.get(key));
			}

			set.remove(item.getPrimaryKey());
			if (MMValueCheck.isNotEmpty(item.getPrimaryKey())) {
				item.setStatus(1);
			} else {
				item.setStatus(2);
			}
			item.setTs((UFDateTime) tsMap.get(item.getPrimaryKey()));
			list.add(item);
		}

		for (String key : set) {
			BomUseOrgVO vo = (BomUseOrgVO) voMap.get(key);
			vo.setStatus(3);
			list.add(vo);
		}

		agg.setChildren(BomUseOrgVO.class, (ISuperVO[]) list.toArray(new BomUseOrgVO[0]));
	}

	private void activityInit(AggBomVO agg, Map<String, Object> paramMap) {
		List<BomActivityVO> list = new ArrayList<BomActivityVO>();
		Set<String> set = (Set) idsMap.get(ACTIVITYTABLE);

		if (set == null) {
			set = new HashSet<String>();
		}

		List<Map<String, Object>> activityInfos = new ArrayList<Map<String, Object>>();
		if (paramMap.get(ACTIVITYTABLE) instanceof List) {
			activityInfos = (List) paramMap.get(ACTIVITYTABLE);
		} else {
			Map<String, Object> activyInfo = (Map) paramMap.get(ACTIVITYTABLE);
			if (MMValueCheck.isNotEmpty(activyInfo)) {
				activityInfos.add(activyInfo);
			}
		}

		for (Map<String, Object> itemMap : activityInfos) {
			BomActivityVO item = new BomActivityVO();
			for (String key : itemMap.keySet()) {
				item.setAttributeValue(key, itemMap.get(key));
			}
			set.remove(item.getPrimaryKey());
			if (MMValueCheck.isNotEmpty(item.getPrimaryKey())) {
				item.setStatus(1);
			} else {
				item.setStatus(2);
			}
			item.setTs((UFDateTime) tsMap.get(item.getPrimaryKey()));
			list.add(item);
		}

		for (String key : set) {
			BomActivityVO vo = (BomActivityVO) voMap.get(key);
			vo.setStatus(3);
			list.add(vo);
		}

		agg.setChildren(BomActivityVO.class, (ISuperVO[]) list.toArray(new BomActivityVO[0]));
	}

	private void outputsInit(AggBomVO agg, Map<String, Object> paramMap) {
		List<BomOutputsVO> list = new ArrayList<BomOutputsVO>();
		Set<String> set = (Set) idsMap.get(OUTPUTSTABLE);

		if (set == null) {
			set = new HashSet<String>();
		}

		List<Map<String, Object>> outputInfos = new ArrayList<Map<String, Object>>();

		if (paramMap.get(OUTPUTSTABLE) instanceof List) {
			outputInfos = (List) paramMap.get(OUTPUTSTABLE);
		} else {
			Map<String, Object> outputInfo = (Map) paramMap.get(OUTPUTSTABLE);
			if (MMValueCheck.isNotEmpty(outputInfo)) {
				outputInfos.add(outputInfo);
			}
		}

		for (Map<String, Object> itemMap : outputInfos) {
			BomOutputsVO item = new BomOutputsVO();
			for (String key : itemMap.keySet()) {
				item.setAttributeValue(key, itemMap.get(key));
			}
			if (MMValueCheck.isNotEmpty(item.getPrimaryKey())) {
				item.setStatus(1);
			} else {
				item.setStatus(2);
			}
			set.remove(item.getPrimaryKey());
			item.setTs((UFDateTime) tsMap.get(item.getPrimaryKey()));
			list.add(item);
		}

		for (String key : set) {
			BomOutputsVO vo = (BomOutputsVO) voMap.get(key);
			vo.setStatus(3);
			list.add(vo);
		}

		agg.setChildren(BomOutputsVO.class, (ISuperVO[]) list.toArray(new BomOutputsVO[0]));
	}

	private UFBoolean getIsExistDefaultVersion(AggBomVO aggvo, String userCode) {
		if (aggvo != null) {
			BomVO headvo = (BomVO) aggvo.getParentVO();
			String pk_org = headvo.getPk_org().toString();
			String materialOid = headvo.getHcmaterialid().toString();
			String hversion = headvo.getHversion();
			String materialVid = null;
			if (MMValueCheck.isNotEmpty(headvo.getHcmaterialvid())) {
				materialVid = headvo.getHcmaterialvid().toString();
			}
			Integer bomtype = headvo.getFbomtype();
			Integer hfbomcategory = headvo.getHfbomcategory();
			if (MMValueCheck.isEmpty(hfbomcategory)) {
				hfbomcategory = Integer.valueOf(1);
			}
			String vsobillcode = headvo.getVsobillcode();
			String vsobillno = headvo.getVsobillno();
			try {
				AggBomVO[] defaultBOM = null;
				if (hfbomcategory.intValue() == 1) {
					defaultBOM = getBomBillQueryService().queryBomByMaterialCond(pk_org, materialOid, materialVid,
							bomtype.intValue());
				} else {
					defaultBOM = getBomBillQueryService().queryOrderBomByMaterialCond(pk_org, vsobillcode, vsobillno,
							bomtype.intValue());
				}
//				IBomBusinessService service = (IBomBusinessService)NCLocator.getInstance().lookup(IBomBusinessService.class);
				if (MMValueCheck.isNotEmpty(defaultBOM)) {
					for (AggBomVO aggBomVO : defaultBOM) {
						BomVO head = (BomVO) aggBomVO.getParent();
						if (VersionTypeEnum.AVAILABLE.equalsValue(head.getHfversiontype())
								&& !head.getCbomid().equals(headvo.getCbomid())) {
							// sdlizheng --添加独立判断--plm三方越过此校验
							if ("gaoning".equals(userCode) || "dlkgsrm".equals(userCode)|| "C029".equals(this.orgCodeFlag)) {
//								AggBomVO afterVO = service.canceldefault(aggBomVO);
							} else if (MESUSERCODE.equals(userCode)) {
								//2025-6-20 添加MES用户判断
							} else {
								return UFBoolean.TRUE;
							}
							// sdlizheng --添加独立判断--plm三方越过此校验
						}
					}

				}
			} catch (BusinessException e) {
				ExceptionUtils.wrappException(e);
			}
		}

		return UFBoolean.FALSE;
	}

	private IBomBillQueryService getBomBillQueryService() {
		return (IBomBillQueryService) NCLocator.getInstance().lookup(IBomBillQueryService.class);
	}

	private void dataSupplement(AggBomVO agg, String userCode) {
		orgSupplement(agg, userCode);

		// 2025年6月20日 - 处理MES用户的hbdefault(默认)字段设置
		handleMesUserDefaultSetting(agg, userCode);

		versionTypeSupplement(agg);

		materialidSupplement(agg);

		itemSupplement(agg);

		outputSupplement(agg);

		useOrgSupplement(agg);
	}

	private void outputSupplement(AggBomVO agg) {
		BomOutputsVO[] outputVOs = (BomOutputsVO[]) agg.getChildren(BomOutputsVO.class);
		handleEvent(outputVOs);
	}

	private void orgSupplement(AggBomVO agg, String userCode) {
		if (MMValueCheck.isEmpty(agg.getParent().getAttributeValue("pk_org_v"))) {
			String pk_org_v = OrgUnitPubService
					.getNewVIDByOrgID(agg.getParent().getAttributeValue("pk_org").toString());
			agg.getParent().setAttributeValue("pk_org_v", pk_org_v);
		}
		Object fbillstatus = agg.getParent().getAttributeValue("fbillstatus");
		if (MMValueCheck.isEmpty(agg.getParent().getAttributeValue("cbomid"))) {
			agg.getParent().setAttributeValue("fbomtype", Integer.valueOf(1));
			agg.getParent().setAttributeValue("hfversiontype", Integer.valueOf(2));
			agg.getParent().setAttributeValue("fbillstatus", Integer.valueOf(-1));
			agg.getParent().setAttributeValue("hfbomsource", Integer.valueOf(1));
			agg.getParent().setAttributeValue("hfbomcategory", Integer.valueOf(1));
			if ("gaoning".equals(userCode) || "dlkgsrm".equals(userCode)|| "C029".equals(this.orgCodeFlag)) {
				// sdlizheng
				// 1、对于之前不存在的BOM，新增时：如果是传自由态，不默认且无效，走标准逻辑，如果传的是审批态默认且有效。2025年4月11日16点28分 start
				if (fbillstatus != null && "1".equals(fbillstatus.toString())) {
					agg.getParent().setAttributeValue("hfversiontype", Integer.valueOf(1));
					agg.getParent().setAttributeValue("hbdefault", UFBoolean.TRUE);
				}else if(fbillstatus != null && "-1".equals(fbillstatus.toString())){
					if("gaoning".equals(userCode)|| "C029".equals(this.orgCodeFlag)){
						agg.getParent().setAttributeValue("hfversiontype", Integer.valueOf(1));
						agg.getParent().setAttributeValue("hbdefault", UFBoolean.TRUE);
					}
				}
				// sdlizheng 1、对于之前不存在的BOM，新增时：如果是传自由态，不默认且无效，如果传的是审批态默认且有效。2025年4月11日16点28分 end
			}
		}

	}

	private void materialidSupplement(AggBomVO agg) {
		BomHeadMtrlParam param = getQueryParam(agg);
		Object assnumObject = agg.getParent().getAttributeValue("hnassparentnum");
		Object numObject = agg.getParent().getAttributeValue("hnparentnum");
		UFDouble assNum = UFDouble.ZERO_DBL;
		UFDouble num = UFDouble.ZERO_DBL;

		if (MMValueCheck.isNotEmpty(assnumObject)) {
			assNum = (UFDouble) agg.getParent().getAttributeValue("hnassparentnum");
		}

		if (MMValueCheck.isNotEmpty(numObject)) {
			num = (UFDouble) agg.getParent().getAttributeValue("hnparentnum");
		}

		IBomBillQueryService service = (IBomBillQueryService) NCLocator.getInstance()
				.lookup(IBomBillQueryService.class);
		BomHeadMtrlResult result = service.queryMtrlInfo(param);
		if (MMValueCheck.isNotEmpty(agg.getParentVO().getAttributeValue("hcmaterialvid"))) {
			agg.getParent().setAttributeValue("hcmaterialvid", result.getMaterialvid());
		}

		agg.getParent().setAttributeValue("hcmaterialname", result.getMtrlname());
		agg.getParent().setAttributeValue("hvplaintext", result.getMtrltruename());
		if (MMValueCheck.isEmpty(agg.getParent().getAttributeValue("hversion"))) {
			agg.getParent().setAttributeValue("hversion", result.getVersion());
		}

		agg.getParent().setAttributeValue("hiswholesetsend", "" + result.getIswhole().booleanValue());
		agg.getParent().setAttributeValue("hisvirtual", "" + result.getIsvertual().booleanValue());

		if (MMValueCheck.isEmpty(agg.getParent().getAttributeValue("hbdefault"))) {
			if ("1.0".equals(result.getVersion())) {

				agg.getParent().setAttributeValue("hbdefault", "true");
			} else {

				agg.getParent().setAttributeValue("hbdefault", "false");
			}
		}

		agg.getParent().setAttributeValue("hvchangerate", result.getMeasureVO().getVchangeRate());

		BomVO bom = new BomVO();
		bom.setHcmeasureid(result.getMeasureVO().getCmeasureid());
		bom.setHcassmeasureid(result.getMeasureVO().getCassMeasures());
		bom.setHvchangerate(result.getMeasureVO().getVchangeRate());

		bom.setHnassparentnum(assNum);
		bom.setHnparentnum(num);

		MeasureParam headParam = new MeasureParam();
		headParam.setCmeasureid("hcmeasureid");
		headParam.setCassMeasures("hcassmeasureid");
		headParam.setVchangeRate("hvchangerate");

		if ((assNum.equals(UFDouble.ZERO_DBL) && num.compareTo(UFDouble.ZERO_DBL) > 0)
				|| (assNum.compareTo(UFDouble.ZERO_DBL) > 0 && num.compareTo(UFDouble.ZERO_DBL) > 0)) {
			MeasureHelper.fillAssNumber(bom, headParam, "hnparentnum", "hnassparentnum");
		} else if (num.equals(UFDouble.ZERO_DBL) && assNum.compareTo(UFDouble.ZERO_DBL) > 0) {

			MeasureHelper.fillAccNumber(bom, headParam, "hnparentnum", "hnassparentnum");
		}

		agg.getParent().setAttributeValue("hcassmeasureid", bom.getHcassmeasureid());
		agg.getParent().setAttributeValue("hcmeasureid", bom.getHcmeasureid());
		agg.getParent().setAttributeValue("hnassparentnum", bom.getHnassparentnum());
		agg.getParent().setAttributeValue("hnparentnum", bom.getHnparentnum());
	}

	private BomHeadMtrlParam getQueryParam(AggBomVO agg) {
		String pk_org = agg.getParentVO().getAttributeValue("pk_org").toString();
		String hcmaterialid = agg.getParentVO().getAttributeValue("hcmaterialid").toString();
		String hcmateriavid = agg.getParentVO().getAttributeValue("hcmaterialvid").toString();
		String pwdkey = null;
		boolean iscust = false;

		int bomtype = BomTypeEnum.PRODUCTFINISH.toIntValue();
		if (MMValueCheck.isNotEmpty(agg.getParentVO().getAttributeValue("fbomtype"))) {
			bomtype = Integer.valueOf(agg.getParentVO().getAttributeValue("fbomtype").toString()).intValue();
		}

		BomHeadMtrlParam param = new BomHeadMtrlParam();
		param.setPk_org(pk_org);
		param.setMaterialid(hcmaterialid);
		param.setMateriavid(hcmateriavid);
		param.setPwdkey(pwdkey);
		param.setBomtype(bomtype);
		param.setIscust(iscust);
		return param;
	}

	private void versionTypeSupplement(AggBomVO agg) {
		if (MMValueCheck.isNotEmpty(agg.getParent().getAttributeValue("hfversiontype"))) {
			if ("2".equals(agg.getParent().getAttributeValue("hfversiontype").toString())) {
				agg.getParent().setAttributeValue("hbdefault", UFBoolean.FALSE);
			}
		} else {
			agg.getParent().setAttributeValue("hbdefault", UFBoolean.TRUE);
		}
	}

	private Map<String, CircularlyAccessibleValueObject> getRelation() {
		Map<String, CircularlyAccessibleValueObject> relation = new HashMap<String, CircularlyAccessibleValueObject>();
		relation.put("wips", new BomWipVO());
		relation.put("loss", new BomLossVO());
		relation.put("repl", new BomReplVO());
		relation.put("select", new BomSelectVO());
		relation.put("resource", new BomItemSourceVO());
		relation.put("pos", new BomPosVO());

		return relation;
	}

	private void itemSupplement(AggBomVO agg) {
		String pk_org = (String) agg.getParent().getAttributeValue("pk_org");
		BomItemVO[] items = agg.getChildrenVO();
		for (BomItemVO item : items) {

			ileadtimenumEvent(item, pk_org, (String) item.getAttributeValue("cmaterialid"),
					(String) item.getAttributeValue("cmaterialvid"));

			fitemtypeEvent(item);

			bprojectmaterialEvent(item);

			bcustommaterial(item);

			fbackflushtypeEvent(item);

			ndisspationumEvent(item, pk_org);

			BomWipVO[] wips = item.getWips();
			if (MMValueCheck.isNotEmpty(wips)) {
				for (BomWipVO vo : wips) {
					wipNumsEvent(vo);
				}
			}

			BomPosVO[] positions = item.getPos();
			if (MMValueCheck.isNotEmpty(positions)) {
				for (BomPosVO vo : positions) {
					posNumsEvent(vo);
				}
			}

			BomLossVO[] lossVOs = item.getLoss();
			if (MMValueCheck.isNotEmpty(lossVOs)) {
				for (BomLossVO vo : lossVOs) {
					lossNumEvent(vo);
				}
			}

			BomReplVO[] replVOs = item.getRepl();
			if (MMValueCheck.isNotEmpty(replVOs)) {
				for (BomReplVO vo : replVOs) {
					replMaterialOidFill(vo);
				}
			}
		}

		handleEvent(items);
	}

	private void replMaterialOidFill(BomReplVO replVO) {
		if (MMValueCheck.isNotEmpty(replVO.getCreplmaterialoid())) {
			return;
		}
		Map<String, MaterialVO> map = getMateriaInfoByVid(replVO.getCreplmaterialvid());
		String pkSource = ((MaterialVO) map.get(replVO.getCreplmaterialvid())).getPk_source();
		replVO.setCreplmaterialoid(pkSource);
	}

	public void ileadtimenumEvent(BomItemVO item, String pk_org, String hcmaterialoid, String hcmaterialvid) {
		try {
			Integer ileadtimenum = item.getIleadtimenum();
			if (ileadtimenum == null) {
				return;
			}
			String pkorg = item.getPk_org();
			if (MMValueCheck.isEmpty(hcmaterialvid) && MMValueCheck.isEmpty(hcmaterialoid)) {
				item.setIleadtimenum(null);
			}

			if (MMValueCheck.isEmpty(hcmaterialvid)) {

				hcmaterialvid = ((MaterialVersionVO) ((IMaterialPubService_C) NCLocator.getInstance()
						.lookup(IMaterialPubService_C.class))
						.queryMaterialBaseInfoByOidPks(new String[] { hcmaterialoid }, new String[] { "pk_material" })
						.get(hcmaterialoid)).toString();
			}
			Map<String, MaterialPlanVO> map = queryMaterialPlanInfoByPks(new String[] { hcmaterialvid }, pkorg,
					new String[] { "fixedahead" });

			UFDouble fixedahead = UFDouble.ZERO_DBL;
			if (MMValueCheck.isNotEmpty(map) && MMValueCheck.isNotEmpty((SuperVO) map.get(hcmaterialvid))
					&& MMValueCheck.isNotEmpty(((MaterialPlanVO) map.get(hcmaterialvid)).getFixedahead())) {
				fixedahead = ((MaterialPlanVO) map.get(hcmaterialvid)).getFixedahead();
			}
			if ((new UFDouble(ileadtimenum.intValue())).compareTo(fixedahead) > 0) {
				item.setIleadtimenum(null);

			}

		} catch (BusinessException e) {
			ExceptionUtils.wrappBusinessException(e.toString());
		}
	}

	public static Map<String, MaterialPlanVO> queryMaterialPlanInfoByPks(String[] pks, String pk_stockorg,
			String[] fields) throws BusinessException {
		Map<String, MaterialPlanVO> map = null;

		List<String> vids = (List) Stream.of(pks).filter(e -> (e != null)).distinct().collect(Collectors.toList());
		if (vids.size() == 0) {
			map = new HashMap<String, MaterialPlanVO>();
		} else {

			map = ((IMaterialPubService) NCLocator.getInstance().lookup(IMaterialPubService.class))
					.queryMaterialPlanInfoByPks((String[]) vids.toArray(new String[0]), pk_stockorg, fields);
		}

		return map;
	}

	private void fitemtypeEvent(BomItemVO item) {
		String fitem = item.getAttributeValue("fitemtype").toString();
		if ("1".equals(fitem)) {
			if (MMValueCheck.isEmpty(item.getFitemsource())) {
				item.setAttributeValue("fitemsource", Integer.valueOf(1));
			}
		} else {
			item.setAttributeValue("fitemsource", null);
		}
	}

	private void bprojectmaterialEvent(BomItemVO item) {
		Object bprojectMaterial = item.getAttributeValue("bprojectmaterial");
		if (MMValueCheck.isEmpty(bprojectMaterial)) {
			item.setAttributeValue("cprojectid", null);
		}
	}

	private void bcustommaterial(BomItemVO item) {
		Object bcustommaterial = item.getAttributeValue("bcustommaterial");
		if (MMValueCheck.isEmpty(bcustommaterial)) {
			item.setAttributeValue("ccustomerid", null);
			item.setAttributeValue("ccustomerid_v", null);
		}
	}

	private void fbackflushtypeEvent(BomItemVO item) {
		Object bcustommaterial = item.getAttributeValue("fbackflushtype");
		if (MMValueCheck.isNotEmpty(bcustommaterial) && "1".equals(bcustommaterial.toString())) {
			item.setAttributeValue("fbackflushtime", null);
		}
	}

	private void ndisspationumEvent(BomItemVO item, String pkorg) {
		int scale = MMBDFactoryParameter.findMMBDDigitNumber(pkorg).intValue();
		UFDouble ndisspationum = (UFDouble) item.getAttributeValue("ndissipationum");
		if (MMValueCheck.isNotEmpty(ndisspationum)) {
			ndisspationum.setScale(scale, 1);
			item.setAttributeValue("ndissipationum", ndisspationum);
		}
	}

	private int getNumberDecimalDigits(String balanceStr) {
		int dcimalDigits = 0;
		int indexOf = balanceStr.indexOf(".");
		if (indexOf > 0) {
			dcimalDigits = balanceStr.length() - 1 - indexOf;
		}
		return dcimalDigits;
	}

	private void wipNumsEvent(BomWipVO vo) {
		UFDouble num = (UFDouble) vo.getAttributeValue("nnum");
		String unitid = (String) vo.getAttributeValue("cassmeasureid");
		UFDouble nnum = (new NumScaleUtil()).calNumScale(num, unitid);
		int scale = getNumberDecimalDigits(nnum.toString());
		vo.setAttributeValue("nnum", nnum.setScale(scale, 1));
	}

	private void posNumsEvent(BomPosVO vo) {
		UFDouble num = (UFDouble) vo.getAttributeValue("nnum");
		String unitid = (String) vo.getAttributeValue("cassmeasureid");
		UFDouble nnum = (new NumScaleUtil()).calNumScale(new UFDouble(num), unitid);
		int scale = getNumberDecimalDigits(nnum.toString());
		vo.setAttributeValue("nnum", nnum.setScale(scale, 1));
	}

	private void lossNumEvent(BomLossVO vo) {
		BomLossVO loss = new BomLossVO();
		loss.setAttributeValue("clunitid", vo.getAttributeValue("clunitid"));
		loss.setAttributeValue("clunitastid", vo.getAttributeValue("clunitastid"));
		loss.setAttributeValue("vlchangerate", vo.getAttributeValue("vlchangerate"));
		loss.setAttributeValue("nlfromastnum", vo.getAttributeValue("nlfromastnum"));
		loss.setAttributeValue("nltoastnum", vo.getAttributeValue("nltoastnum"));
		MeasureParam headParam = new MeasureParam();
		headParam.setCmeasureid("clunitid");
		headParam.setCassMeasures("clunitastid");
		headParam.setVchangeRate("vlchangerate");
		MeasureHelper.fillAccNumber(loss, headParam, "nlfromnum", "nlfromastnum");
		double fromNum = loss.getNlfromnum().doubleValue();

		vo.setAttributeValue("nlfromnum", Double.valueOf(fromNum));

		MeasureHelper.fillAccNumber(loss, headParam, "nltonum", "nltoastnum");
		double ltonum = loss.getNltonum().doubleValue();

		vo.setAttributeValue("nltonum", Double.valueOf(ltonum));
	}

	private BomWipVO[] getWipVos(List<Map<String, Object>> infos) {
		List<BomWipVO> list = new ArrayList<BomWipVO>();
		Set<String> set = (Set) idsMap.get(WIPTABLE);
		if (set == null) {
			set = new HashSet<String>();
		}

		for (Map<String, Object> info : infos) {
			BomWipVO vo = new BomWipVO();
			for (String key : info.keySet()) {
				vo.setAttributeValue(key, info.get(key));
			}
			set.remove(vo.getPrimaryKey());
			if (MMValueCheck.isNotEmpty(vo.getPrimaryKey())) {
				vo.setStatus(1);
			} else {
				vo.setStatus(2);
			}
			vo.setTs((UFDateTime) tsMap.get(vo.getPrimaryKey()));
			list.add(vo);
		}

		for (String key : set) {
			BomWipVO vo = (BomWipVO) voMap.get(key);
			vo.setStatus(3);
			list.add(vo);
		}

		return (BomWipVO[]) list.toArray(new BomWipVO[0]);
	}

	private BomPosVO[] getPosVos(List<Map<String, Object>> infos) {
		List<BomPosVO> list = new ArrayList<BomPosVO>();
		Set<String> set = (Set) idsMap.get(POSITIONTABLE);

		if (set == null) {
			set = new HashSet<String>();
		}

		for (Map<String, Object> info : infos) {
			BomPosVO vo = new BomPosVO();
			for (String key : info.keySet()) {
				vo.setAttributeValue(key, info.get(key));
			}
			set.remove(vo.getPrimaryKey());
			if (MMValueCheck.isNotEmpty(vo.getPrimaryKey())) {
				vo.setStatus(1);
			} else {
				vo.setStatus(2);
			}
			vo.setTs((UFDateTime) tsMap.get(vo.getPrimaryKey()));
			list.add(vo);
		}

		for (String key : set) {
			BomPosVO vo = (BomPosVO) voMap.get(key);
			vo.setStatus(3);
			list.add(vo);
		}
		return (BomPosVO[]) list.toArray(new BomPosVO[0]);
	}

	private BomReplVO[] getReplVos(List<Map<String, Object>> infos) {
		List<BomReplVO> list = new ArrayList<BomReplVO>();
		Set<String> set = (Set) idsMap.get(REPLTABLE);

		if (set == null) {
			set = new HashSet<String>();
		}

		for (Map<String, Object> info : infos) {
			BomReplVO vo = new BomReplVO();
			for (String key : info.keySet()) {
				vo.setAttributeValue(key, info.get(key));
			}
			set.remove(vo.getPrimaryKey());
			if (MMValueCheck.isNotEmpty(vo.getPrimaryKey())) {
				vo.setStatus(1);
			} else {
				vo.setStatus(2);
			}
			vo.setTs((UFDateTime) tsMap.get(vo.getPrimaryKey()));
			list.add(vo);
		}

		for (String key : set) {
			BomReplVO vo = (BomReplVO) voMap.get(key);
			vo.setStatus(3);
			list.add(vo);
		}
		return (BomReplVO[]) list.toArray(new BomReplVO[0]);
	}

	private BomLossVO[] getLossVos(List<Map<String, Object>> infos, BomItemVO item) {
		List<BomLossVO> list = new ArrayList<BomLossVO>();
		Set<String> set = (Set) idsMap.get(LOSSTABLE);

		if (set == null) {
			set = new HashSet<String>();
		}

		for (Map<String, Object> info : infos) {
			BomLossVO vo = new BomLossVO();
			for (String key : info.keySet()) {
				vo.setAttributeValue(key, info.get(key));
			}
			set.remove(vo.getPrimaryKey());
			if (MMValueCheck.isNotEmpty(vo.getPrimaryKey())) {
				vo.setStatus(1);
			} else {
				vo.setStatus(2);
			}
			vo.setTs((UFDateTime) tsMap.get(vo.getPrimaryKey()));
			vo.setAttributeValue("clunitastid", item.getAttributeValue("cassmeasureid"));
			vo.setAttributeValue("clunitid", item.getAttributeValue("cmeasureid"));
			list.add(vo);
		}

		for (String key : set) {
			BomLossVO vo = (BomLossVO) voMap.get(key);
			vo.setStatus(3);
			list.add(vo);
		}
		return (BomLossVO[]) list.toArray(new BomLossVO[0]);
	}

	public BomItemVO[] handleEvent(BomItemVO[] items) {
		List<String> itemCmaterialvids = new ArrayList<String>();
		for (BomItemVO item : items) {
			if (MMValueCheck.isNotEmpty(item.getCmaterialvid())) {
				itemCmaterialvids.add(item.getCmaterialvid());
			}
		}
		Map<String, BomMaterialParam> materialMap = new HashMap<String, BomMaterialParam>();
		Map<String, MeasureVO> measurevoMap = new HashMap<String, MeasureVO>();

		String pkorg = items[0].getPk_org();
		if (itemCmaterialvids.size() > 0) {
			try {
				materialMap = ((IBomBillQueryService) NCLocator.getInstance().lookup(IBomBillQueryService.class))
						.queryMaterialInfo(pkorg, (String[]) itemCmaterialvids.toArray(new String[0]));
				IMeasesureService service = (IMeasesureService) NCLocator.getInstance().lookup(IMeasesureService.class);
				measurevoMap.putAll(service.getMeasureInfoMap((String[]) itemCmaterialvids.toArray(new String[0])));
			} catch (BusinessException e1) {
				ExceptionUtils.wrappBusinessException(e1.toString());
			}
		}

		for (BomItemVO item : items) {
			if (MMValueCheck.isNotEmpty(item.getCmaterialvid())) {
				item.setVitemversion(null);
				item.setVpackversion(null);
				item.setVfree1(null);
				item.setVfree2(null);
				item.setVfree3(null);
				item.setVfree4(null);
				item.setVfree5(null);
				item.setVfree6(null);
				item.setVfree7(null);
				item.setVfree8(null);
				item.setVfree9(null);
				item.setVfree10(null);

				if (measurevoMap.containsKey(item.getCmaterialvid())) {
					if (MMValueCheck.isEmpty(item.getVchangerate())) {
						item.setVchangerate(((MeasureVO) measurevoMap.get(item.getCmaterialvid())).getVchangeRate());
					}

					item.setCmeasureid(((MeasureVO) measurevoMap.get(item.getCmaterialvid())).getCmeasureid());

					item.setCassmeasureid(((MeasureVO) measurevoMap.get(item.getCmaterialvid())).getCassMeasures());
				}

				setMaterialInfo(materialMap, item);
				MeasureParam headParam = new MeasureParam();
				headParam.setCmaterialvid("cmaterialvid");
				headParam.setCmeasureid("cmeasureid");
				headParam.setCassMeasures("cassmeasureid");
				headParam.setVchangeRate("vchangerate");
				MeasureHelper.fillAccNumber(item, headParam, "nitemnum", "nassitemnum");
			} else {

				item.setBdeliver(UFBoolean.FALSE);
				item.setAttributeValue("iscreatesonprodorder", UFBoolean.FALSE);
				item.setAttributeValue("nbfixshrinkastnum", null);
				item.setAttributeValue("nbfixshrinknum", null);
				item.setAttributeValue("ndissipationum", null);
				item.setAttributeValue("fbackflushtime", null);
				item.setAttributeValue("fbackflushtype", null);
				item.setAttributeValue("bbunibatch", UFBoolean.FALSE);
				item.setVfree1(null);
				item.setVfree2(null);
				item.setVfree3(null);
				item.setVfree4(null);
				item.setVfree5(null);
				item.setVfree6(null);
				item.setVfree7(null);
				item.setVfree8(null);
				item.setVfree9(null);
				item.setVfree10(null);
			}
		}

		return items;
	}

	void setMaterialInfo(Map<String, BomMaterialParam> materialMap, BomItemVO item) {
		String materialvid = item.getCmaterialvid();
		if (!materialMap.containsKey(materialvid)) {
			return;
		}

		BomMaterialParam materialParam = (BomMaterialParam) materialMap.get(materialvid);
		if (materialParam == null) {
			return;
		}
		if (UFBoolean.TRUE == materialParam.getIsvirtual()) {

			item.setBbsteploss(UFBoolean.FALSE);
			item.setNbfixshrinknum(null);
			item.setNbfixshrinkastnum(null);
			item.setNdissipationum(null);
			item.setIleadtimenum(null);
			item.setBupint(UFBoolean.FALSE);

			item.setBisvirtual(UFBoolean.TRUE);
		} else {
			item.setAttributeValue("nbfixshrinknum", materialParam.getNfixshrinknum());

			MeasureParam headParam = new MeasureParam();
			headParam.setCmaterialvid("cmaterialvid");
			headParam.setCmeasureid("cmeasureid");
			headParam.setCassMeasures("cassmeasureid");
			headParam.setVchangeRate("vchangerate");
			MeasureHelper.fillOnlyNumAssNumQtNum(item, headParam, "nbfixshrinknum", "nbfixshrinkastnum", null);

			item.setAttributeValue("ndissipationum", materialParam.getNdissipationnum());
		}

		if (MMValueCheck.isEmpty(item.getBdeliver())) {
			item.setAttributeValue("bdeliver", materialParam.getBdeliver());
		}

		if (MMValueCheck.isEmpty(item.getFbackflushtype())) {
			item.setAttributeValue("fbackflushtype", materialParam.getFbackflushtype());
		}

		if (MMValueCheck.isEmpty(item.getFbackflushtime())) {
			item.setAttributeValue("fbackflushtime", materialParam.getFbackflushtime());
		}

		if (MMValueCheck.isEmpty(item.getBbunibatch())) {
			item.setAttributeValue("bbunibatch", materialParam.getBunibatch());
		}

		if (BackflushTypeEnum.NOBACKFLUSH.equalsValue(materialParam.getFbackflushtype())) {
			item.setAttributeValue("fbackflushtime", null);

		} else if (BackflushTypeEnum.AUTOBACKFLUSH.equalsValue(materialParam.getFbackflushtype())
				|| BackflushTypeEnum.EXCHANGEBACKFLUSH.equalsValue(materialParam.getFbackflushtype())) {
			if (MMValueCheck.isEmpty(materialParam.getFbackflushtime())) {
				item.setAttributeValue("fbackflushtime", Integer.valueOf(BackflushTimeEnum.MMBOM.toIntValue()));
			}
		} else if (MMValueCheck.isEmpty(materialParam.getFbackflushtype())) {

			item.setAttributeValue("fbackflushtype", Integer.valueOf(BackflushTypeEnum.EXCHANGEBACKFLUSH.toIntValue()));
			item.setAttributeValue("fbackflushtime", Integer.valueOf(BackflushTimeEnum.MMBOM.toIntValue()));
		}

		item.setAttributeValue("iscreatesonprodorder", materialParam.getIscreatesonprodorder());
	}

	public BomOutputsVO[] handleEvent(BomOutputsVO[] items) {
		Map<String, BomMaterialParam> materialMap = new HashMap<String, BomMaterialParam>();
		for (BomOutputsVO item : items) {
			try {
				materialMap = ((IBomBillQueryService) NCLocator.getInstance().lookup(IBomBillQueryService.class))
						.queryMaterialInfo(item.getPk_org(), new String[] { item.getCmaterialvid() });

				Map<String, MeasureVO> measurevoMap = new HashMap<String, MeasureVO>();
				IMeasesureService service = (IMeasesureService) NCLocator.getInstance().lookup(IMeasesureService.class);
				measurevoMap.putAll(service.getMeasureInfoMap(new String[] { item.getCmaterialvid() }));
				if (measurevoMap.containsKey(item.getCmaterialvid())) {
					item.setVchangerate(((MeasureVO) measurevoMap.get(item.getCmaterialvid())).getVchangeRate());
					item.setCastunitid(((MeasureVO) measurevoMap.get(item.getCmaterialvid())).getCassMeasures());
					item.setCunitid(((MeasureVO) measurevoMap.get(item.getCmaterialvid())).getCmeasureid());
				}

				Map<String, MaterialVO> cmaterialMap = getMateriaInfoByVid(item.getCmaterialvid());
				MaterialVO materialVO = (MaterialVO) cmaterialMap.get(item.getCmaterialvid());
				item.setCmaterialid(materialVO.getPk_source());
			} catch (BusinessException e1) {
				ExceptionUtils.wrappBusinessException(e1.toString());
			}
			MeasureParam headParam = new MeasureParam();
			headParam.setCmaterialvid("cmaterialvid");
			headParam.setCmeasureid("cunitid");
			headParam.setCassMeasures("castunitid");
			headParam.setVchangeRate("vchangerate");
			MeasureHelper.fillAccNumber(item, headParam, "noutputnum", "nastoutputnum");

			item.setVfree1(null);
			item.setVfree2(null);
			item.setVfree3(null);
			item.setVfree4(null);
			item.setVfree5(null);
			item.setVfree6(null);
			item.setVfree7(null);
			item.setVfree8(null);
			item.setVfree9(null);
			item.setVfree10(null);
		}

		return items;
	}

	private JSONString requiredCheck(AggBomVO agg) {
		Object hcmaterialid = agg.getParent().getAttributeValue("hcmaterialid");

		Object fbomtype = agg.getParent().getAttributeValue("fbomtype");

		Object hversion = agg.getParent().getAttributeValue("hversion");

		if (MMValueCheck.isEmpty(hcmaterialid) || MMValueCheck.isEmpty(fbomtype) || MMValueCheck.isEmpty(hversion)) {
			return ResultMessageUtil.exceptionToJSON("传入数据异常，表头信息存在未填的必输项", "1");
		}

		BomItemVO[] items = agg.getChildrenVO();
		for (int i = 0; i < items.length; i++) {
			BomItemVO item = items[i];

			String cmaterialvid = item.getCmaterialvid();

			UFDouble nassitemnum = item.getNassitemnum();

			Integer ibasenum = item.getIbasenum();

			Integer fitemtype = item.getFitemtype();

			Integer fsupplymode = item.getFsupplymode();

			Integer fbackflushtype = item.getFbackflushtype();

			Integer fcontrol = item.getFcontrol();

			UFDate cbeginperiod = item.getCbeginperiod();

			UFDate cendperiod = item.getCendperiod();

			if (MMValueCheck.isEmpty(cmaterialvid) || MMValueCheck.isEmpty(nassitemnum)
					|| MMValueCheck.isEmpty(ibasenum) || MMValueCheck.isEmpty(fitemtype)
					|| MMValueCheck.isEmpty(fsupplymode) || MMValueCheck.isEmpty(fcontrol)
					|| MMValueCheck.isEmpty(cbeginperiod) || MMValueCheck.isEmpty(cendperiod)
					|| MMValueCheck.isEmpty(fbackflushtype)) {
				return ResultMessageUtil.exceptionToJSON("传入数据异常，子表材料第" + i + 1 + "行存在未填的必输项", "1");
			}
		}

		BomOutputsVO[] bomOutputsVO = (BomOutputsVO[]) agg.getChildren(BomOutputsVO.class);

		for (int j = 0; j < bomOutputsVO.length; j++) {
			BomOutputsVO outputsVO = bomOutputsVO[j];

			Integer foutputtype = outputsVO.getFoutputtype();

			String cmaterialvid = outputsVO.getCmaterialvid();

			if (MMValueCheck.isEmpty(foutputtype) || MMValueCheck.isEmpty(cmaterialvid)) {
				return ResultMessageUtil.exceptionToJSON("传入数据异常，联副产品第" + j + 1 + "行存在未填的必输项", "1");
			}
		}

		return null;
	}

	private Map<String, MaterialVO> getMateriaInfoByVid(String materialVid) {
		Map<String, MaterialVO> materialSourceMap = new HashMap<String, MaterialVO>();
		try {
			materialSourceMap = ((IMaterialPubService_C) NCLocator.getInstance().lookup(IMaterialPubService_C.class))
					.queryMaterialBaseInfoByPks(new String[] { materialVid },
							new String[] { "pk_source", "graphid", "materialspec", "materialtype" });

		} catch (BusinessException e1) {
			ResultMessageUtil.exceptionToJSON(e1);
		}
		return materialSourceMap;
	}

	private void useOrgSupplement(AggBomVO agg) {
		BomUseOrgVO[] useOrgVOs = (BomUseOrgVO[]) agg.getChildren(BomUseOrgVO.class);
		if (MMValueCheck.isNotEmpty(useOrgVOs))
			for (BomUseOrgVO item : useOrgVOs) {

				item.setCbomid((String) agg.getParentVO().getAttributeValue("cbomid"));
				item.setPk_org((String) agg.getParentVO().getAttributeValue("pk_org"));
				item.setPk_org_v((String) agg.getParentVO().getAttributeValue("pk_org_v"));
				item.setPk_useorg((String) agg.getParentVO().getAttributeValue("pk_org"));
				item.setPk_useorg_v((String) agg.getParentVO().getAttributeValue("pk_org_v"));
			}
	}


	private void handleCableOrgJinSiWeiBomVersion(AggBomVO agg) {
		try {
			String pk_org = (String) agg.getParent().getAttributeValue("pk_org");
			String hcmaterialid = (String) agg.getParent().getAttributeValue("hcmaterialid");
			String hversion = agg.getParent().getAttributeValue("hversion").toString();
			String cbomid = (String) agg.getParent().getAttributeValue("cbomid");
			String hvnote = (String) agg.getParent().getAttributeValue("hvnote");

			// 检查必要字段
			if (MMValueCheck.isEmpty(hcmaterialid)  || MMValueCheck.isEmpty(hversion)) {
				return;
			}

			// 判断是否为电缆组织（组织编码C034）且备注包含"金思维"
			boolean isCableOrgJinSiWei = isCableOrganizationWithJinSiWei(pk_org, hvnote);

			if (isCableOrgJinSiWei) {
				// 计算版本号
				String calculatedVersion = calculateBomVersion(pk_org, hcmaterialid );
				agg.getParent().setAttributeValue("hversion", calculatedVersion);
			}
		} catch (Exception e) {
			ExceptionUtils.wrappBusinessException("同步电缆组织金思维BOM版本号处理异常：" + e.getMessage());
		}
	}

	/**
	 * 判断是否为电缆组织且备注包含金思维
	 * @param pk_org 组织主键
	 * @param hvnote 备注信息
	 * @return 是否符合条件
	 */
	private boolean isCableOrganizationWithJinSiWei(String pk_org, String hvnote) {
		if (MMValueCheck.isEmpty(pk_org)) {
			return false;
		}

		try {
			// 查询组织编码
			String sql = "SELECT code FROM org_orgs WHERE dr = 0 and pk_org = ?";
			SQLParameter param = new SQLParameter();
			param.addParam(pk_org);
			String orgCode = (String) DAO.executeQuery(sql, param, new ColumnProcessor());

			// 使用统一的组织判断方法
			boolean isCableOrg = HTTP_POST_OTHER_SYS.checkIfIncludeOrg(orgCode);

			// 判断备注是否包含"金思维"
			boolean containsJinSiWei = MMValueCheck.isNotEmpty(hvnote) && hvnote.contains("金思维");

			return isCableOrg && containsJinSiWei;
		} catch (Exception e) {
			// 查询异常时返回false
			return false;
		}
	}

	/**
	 * 计算BOM版本号
	 * @param pk_org 组织主键
	 * @param hcmaterialid 物料编码
	 * @return 计算出的版本号
	 */
	private String calculateBomVersion(String pk_org, String hcmaterialid ) throws BusinessException {
		try {
			// 构建查询条件
			StringBuilder sql = new StringBuilder();
            sql.append("SELECT MAX(TO_NUMBER(hversion)) as max_version ");
            sql.append("FROM bd_bom ");
			sql.append("WHERE dr = 0 and pk_org = ? ");

			SQLParameter param = new SQLParameter();
			param.addParam(pk_org);

			// 根据物料情况添加查询条件
            sql.append("AND hcmaterialid = ? ");
            param.addParam(hcmaterialid);

            // 只查询数字版本号，排除非数字版本
            sql.append("AND REGEXP_LIKE(hversion, '^[0-9]+$') ");
            // 如果查询不到数据，默认版本号为1；否则最大版本号加1
            Object mayBeNullVersion = DAO.executeQuery(sql.toString(), param, new ColumnProcessor());
            String number = Objects.isNull(mayBeNullVersion) ? "1" : DAO.executeQuery(sql.toString(), param, new ColumnProcessor()).toString();
            return String.valueOf(Long.parseLong(number)+1);

        } catch (Exception e) {
			throw new BusinessException("计算BOM版本号异常：" + e.getMessage());
		}
	}

	/**
	 * 处理MES用户的hbdefault字段设置逻辑
	 * 2025年6月20日新增 - 专门用于MES用户的处理
	 * 仿照orgSupplement方法编写
	 * @auther 毛磊
	 * @param agg AggBomVO对象
	 * @param userCode 用户代码
	 */
	private void handleMesUserDefaultSetting(AggBomVO agg, String userCode) {
		// 仅针对MES用户进行处理
		if (!MESUSERCODE.equals(userCode)) {
			return;
		}

		Object fbillstatus = agg.getParent().getAttributeValue("fbillstatus");
		
		// MES用户新增时，按照与gaoning和dlkgsrm相同的逻辑处理hbdefault字段
		if (fbillstatus != null && "1".equals(fbillstatus.toString())) {
			// 审批态时：设置为默认且有效
			agg.getParent().setAttributeValue("hfversiontype", Integer.valueOf(1));
			agg.getParent().setAttributeValue("hbdefault", UFBoolean.TRUE);
		} else if (fbillstatus != null && "-1".equals(fbillstatus.toString())) {
			// 自由态时：设置为默认且有效（与gaoning用户逻辑一致）
			agg.getParent().setAttributeValue("hfversiontype", Integer.valueOf(1));
			agg.getParent().setAttributeValue("hbdefault", UFBoolean.TRUE);
		}
	}
}
