diff --git a/ic/src/public/nc/vo/ic/m4n/entity/deal/TransformVOChecker.java b/ic/src/public/nc/vo/ic/m4n/entity/deal/TransformVOChecker.java
new file mode 100644
index 0000000..ca51ff6
--- /dev/null
+++ b/ic/src/public/nc/vo/ic/m4n/entity/deal/TransformVOChecker.java
@@ -0,0 +1,429 @@
+package nc.vo.ic.m4n.entity.deal;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import nc.bs.dao.BaseDAO;
+import nc.bs.dao.DAOException;
+import nc.bs.ic.general.util.RuleUtils;
+import nc.bs.ic.pub.env.ICBSContext;
+import nc.vo.bd.material.stock.MaterialStockVO;
+import nc.vo.ic.invadjust.lang.InvAdjustRes;
+import nc.vo.ic.m4n.entity.TransformBodyVO;
+import nc.vo.ic.m4n.entity.TransformRowFlag;
+import nc.vo.ic.m4n.entity.TransformVO;
+import nc.vo.ic.pub.define.ICPubMetaNameConst;
+import nc.vo.ic.pub.util.CollectionUtils;
+import nc.vo.ic.pub.util.StringUtil;
+import nc.vo.ic.pub.util.VOEntityUtil;
+import nc.vo.ic.special.check.SpecialBillEntityCheck;
+import nc.vo.pub.BusinessException;
+import nc.vo.pub.VOStatus;
+import nc.vo.pub.lang.UFBoolean;
+
+/**
+ *
+ * 本类主要完成以下功能: 形态转换数据校验 1.行类型校验 2.转换前后的物料维度校验 3.必输项及数量、主数量非空校验 限BS端调用
+ *
+ *
+ *
+ *
+ *
+ * @version 6.0
+ * @since 6.0
+ * @author chennn
+ * @time 2010-5-31 下午04:35:35
+ */
+public class TransformVOChecker {
+
+ public void checkNullItem(TransformVO bill) throws BusinessException {
+
+ new SpecialBillEntityCheck().checkNullItem(bill);
+ List errVendorRows = new ArrayList();// 供应商
+ List errProductRows = new ArrayList();// 生产厂商
+ List errProjectRows = new ArrayList();// 项目
+ List errCffileidRows = new ArrayList();// 特征码
+ List errStateRows = new ArrayList();
+ List errNumRows = new ArrayList();// 数量和主数量
+ List errCasscustRows = new ArrayList();
+ ICBSContext context = new ICBSContext();
+ for (TransformBodyVO body : bill.getBodys()) {
+ // 过滤已经删除或者没有修改的表体行
+ if (body.getStatus() == VOStatus.DELETED || body.getStatus() == VOStatus.UNCHANGED) {
+ continue;
+ }
+ String cmaterialvid = body.getCmaterialvid();
+ if (!StringUtil.isSEmptyOrNull(cmaterialvid) && (body.getNnum() == null || body.getNassistnum() == null)) {
+ errNumRows.add(body.getCrowno());
+ }
+ if (this.isVendorChosen(cmaterialvid, context) && StringUtil.isSEmptyOrNull(body.getCvendorid())) {
+ errVendorRows.add(body.getCrowno());
+ }
+ // 泰开项目客开
+
+ // 项目字段根据库存信息页签-可用量按辅助属性检查是否勾选进行判断
+ String pk_org = bill.getHead().getPk_org();
+ Boolean needCheckProd = checkProdect(cmaterialvid, pk_org);
+ if (needCheckProd&&this.isProductorChosen(cmaterialvid, context) && StringUtil.isSEmptyOrNull(body.getCproductorid())) {
+ errProductRows.add(body.getCrowno());
+ }
+ // 项目字段根据库存信息页签-可用量按辅助属性检查是否勾选进行判断
+ Boolean needCheckProject = checkProject(cmaterialvid, pk_org);
+ if (needCheckProject&&this.isProjectChosen(cmaterialvid, context) && StringUtil.isSEmptyOrNull(body.getCprojectid())) {
+ errProjectRows.add(body.getCrowno());
+ }
+ if (this.isInvStateManage(cmaterialvid, context) && StringUtil.isSEmptyOrNull(body.getCstateid())) {
+ errStateRows.add(body.getCrowno());
+ }
+ if (this.isCasscustChosen(cmaterialvid, context) && StringUtil.isSEmptyOrNull(body.getCasscustid())) {
+ errCasscustRows.add(body.getCrowno());
+ }
+ if (this.isCffileidChosen(cmaterialvid, context) && StringUtil.isSEmptyOrNull(body.getCffileid())) {
+ errCffileidRows.add(body.getCrowno());
+ }
+
+ }
+ RuleUtils util = new RuleUtils();
+ util.showErrByRows(errVendorRows, InvAdjustRes.getVendorNullErr());
+ util.showErrByRows(errProductRows, InvAdjustRes.getProductorNullErr());
+ util.showErrByRows(errProjectRows, InvAdjustRes.getProjectNullErr());
+ util.showErrByRows(errStateRows, InvAdjustRes.getStateNullErr());
+ util.showErrByRows(errNumRows, InvAdjustRes.getNumNullErr());
+ util.showErrByRows(errCasscustRows, InvAdjustRes.getCasscustNullErr());
+ util.showErrByRows(errCffileidRows, InvAdjustRes.getCffileidNullErr());
+
+ }
+
+ /**
+ * 根据物料查询物料库存信息页签-可用量按辅助属性检查是否勾选进行判断
+ *
+ * @param cmaterialvid
+ * @param pk_org
+ * @return
+ */
+ private Boolean checkProject(String cmaterialvid, String pk_org) {
+ String whereSql = " pk_material='" + cmaterialvid + "' and pk_org='" + pk_org + "' and nvl(dr,0)=0 ";
+ List list = null;
+ try {
+ list = (List) new BaseDAO().retrieveByClause(MaterialStockVO.class, whereSql);
+ } catch (DAOException e) {
+ e.printStackTrace();
+ }
+ if (list != null && list.size() > 0) {
+ return list.get(0).getFixasst2()==null?false:list.get(0).getFixasst2().booleanValue();
+ }
+ return true;
+ }
+
+ /**
+ * 根据物料查询物料库存信息页签-可用量按辅助属性检查是否勾选进行判断
+ *
+ * @param cmaterialvid
+ * @param pk_org
+ * @return
+ */
+ private Boolean checkProdect(String cmaterialvid, String pk_org) {
+ String whereSql = " pk_material='" + cmaterialvid + "' and pk_org='" + pk_org + "' and nvl(dr,0)=0 ";
+ List list = null;
+ try {
+ list = (List) new BaseDAO().retrieveByClause(MaterialStockVO.class, whereSql);
+ } catch (DAOException e) {
+ e.printStackTrace();
+ }
+ if (list != null && list.size() > 0) {
+ return list.get(0).getFixasst4() == null ? false : list.get(0).getFixasst4().booleanValue();
+ }
+ return true;
+ }
+
+ public List checkRowType(TransformVO bill) throws BusinessException {
+ TransformBodyVO[] bodyvos = bill.getBodys();
+ int bodyLength = bodyvos.length;
+ if (bodyLength <= 0) {
+ return null;
+ }
+ if (bodyLength < 2) {
+ throw new BusinessException(InvAdjustRes.getRowLengErr());
+ }
+ List beforeIndex = new ArrayList();
+ for (int i = 0; i < bodyLength; i++) {
+ if (null == bodyvos[i].getFbillrowflag()) {
+ throw new BusinessException(InvAdjustRes.getRowTypeNullErr());
+ }
+ if (bodyvos[i].getFbillrowflag().equals(TransformRowFlag.BEFORECONVERT.value())
+ && VOStatus.DELETED != bodyvos[i].getStatus()) {
+ beforeIndex.add(i);
+ }
+ }
+ if (!bodyvos[0].getFbillrowflag().equals(TransformRowFlag.BEFORECONVERT.value())
+ || !bodyvos[bodyLength - 1].getFbillrowflag().equals(TransformRowFlag.AFTERCONVERT.value())) {
+ throw new BusinessException(InvAdjustRes.getFirstAndLastRowTypeErr());
+ }
+ if (beforeIndex.size() > bodyLength / 2) {
+ throw new BusinessException(InvAdjustRes.getTransformRowTypeErr());
+ }
+ for (int i = 0, j = i + 1; j < beforeIndex.size(); i++, j++) {
+ int currentindex = beforeIndex.get(i);
+ int nextindex = beforeIndex.get(j);
+ if (nextindex == currentindex + 1) {
+ throw new BusinessException(InvAdjustRes.getTransformRowTypeErr());
+ }
+ }
+ return beforeIndex;
+
+ }
+
+ private List getBodysButDelete(TransformBodyVO[] bodyVOs) {
+ List aftertempRows = new ArrayList();
+ for (TransformBodyVO bodyVO : bodyVOs) {
+ if (VOStatus.DELETED == bodyVO.getStatus()) {
+ continue;
+ }
+ aftertempRows.add(bodyVO);
+ }
+ return aftertempRows;
+ }
+
+ /**
+ * 方法功能描述:
+ *
+ * 检查转换前后的行内容是否存在转换前行等于转换后的行 参数说明
+ *
+ * @param bill
+ * @throws BusinessException
+ *
+ * @since 6.0
+ * @author chennn
+ * @time 2010-6-1 下午03:06:04
+ */
+ public void checkTranformItem(TransformVO bill, List beforeIndex) throws BusinessException {
+ TransformBodyVO[] bodyVOs = bill.getBodys();
+ Map> errInfo = new HashMap>();
+ List aftertempRows = this.getBodysButDelete(bodyVOs);
+ if (beforeIndex.size() == 1) {
+ TransformBodyVO beforeRow = bodyVOs[beforeIndex.get(0)];
+ List afterRows = aftertempRows.subList(1, aftertempRows.size());
+ List errRows = this.isBeforeSameWithAfter(beforeRow, afterRows);
+ if (errRows.size() > 0) {
+ errInfo.put(beforeRow, errRows);
+ this.showItemSameErr(errInfo);
+ }
+ } else {
+ List errBeforeRow = new ArrayList();
+ for (int i = 0, j = i + 1; j < beforeIndex.size(); i++, j++) {
+ int currentIndex = beforeIndex.get(i);
+ int nextIndex = beforeIndex.get(j);
+ TransformBodyVO beforeRow = bodyVOs[currentIndex];
+ List afterRows = new ArrayList();
+ for (int k = currentIndex + 1; k < nextIndex; k++) {
+ // 过滤已删除表体行
+ if (VOStatus.DELETED == bodyVOs[k].getStatus()) {
+ continue;
+ }
+ afterRows.add(bodyVOs[k]);
+ }
+ List errAfters = this.isBeforeSameWithAfter(beforeRow, afterRows);
+ if (errAfters.size() > 0) {
+ errBeforeRow.add(beforeRow);
+ errInfo.put(beforeRow, errAfters);
+ }
+ }
+ int lastBeforeIndex = beforeIndex.get(beforeIndex.size() - 1);
+ TransformBodyVO beforeRow = bodyVOs[lastBeforeIndex];
+// List afterBodyRows = aftertempRows.subList(
+// lastBeforeIndex + 1, aftertempRows.size());
+
+ // begin --调整最后一次校验表体行取值方式 lihui13 20180915
+ List afterBodyRows = new ArrayList();
+ int k = lastBeforeIndex + 1;
+ while (k != bodyVOs.length) {
+ if (k > bodyVOs.length) {
+ break;
+ }
+ if (VOStatus.DELETED == bodyVOs[k].getStatus()) {
+ k++;
+ continue;
+ }
+ afterBodyRows.add(bodyVOs[k]);
+ k++;
+ }
+ // end
+ List errAfters = this.isBeforeSameWithAfter(beforeRow, afterBodyRows);
+ if (errAfters.size() > 0) {
+ errBeforeRow.add(beforeRow);
+ errInfo.put(beforeRow, errAfters);
+ }
+ this.showItemSameErr(errInfo);
+ }
+ }
+
+ private String[] getKeys(TransformBodyVO beforeRow, String[] initFields) {
+
+ List keys = new ArrayList();
+ CollectionUtils.addArrayToList(keys, initFields);
+ if (keys.contains(TransformBodyVO.VFREE_PREFIX)) {
+ for (int i = 1; i <= TransformBodyVO.VREE_NUM; i++) {
+ String vfree_i = TransformBodyVO.VFREE_PREFIX + i;
+ keys.add(vfree_i);
+ }
+ }
+ String cmaterialvid = beforeRow.getCmaterialvid();
+ ICBSContext context = new ICBSContext();
+ if (this.isVendorChosen(cmaterialvid, context)) {
+ keys.add(TransformBodyVO.CVENDORID);
+ }
+ if (this.isProductorChosen(cmaterialvid, context)) {
+ keys.add(TransformBodyVO.CPRODUCTORID);
+ }
+ if (this.isProjectChosen(cmaterialvid, context)) {
+ keys.add(TransformBodyVO.CPROJECTID);
+ }
+ if (this.isInvStateManage(cmaterialvid, context)) {
+ keys.add(TransformBodyVO.CSTATEID);
+ }
+ if (this.isCffileidChosen(cmaterialvid, context)) {
+ keys.add(ICPubMetaNameConst.CFFILEID);
+ }
+ return keys.toArray(new String[keys.size()]);
+ }
+
+ private List isBeforeSameWithAfter(TransformBodyVO beforeRow, List afterRows) {
+
+ String[] fields = new String[] { TransformBodyVO.CMATERIALVID, TransformBodyVO.CASTUNITID,
+ TransformBodyVO.VBATCHCODE, TransformBodyVO.VFREE_PREFIX, TransformBodyVO.CASSCUSTID };
+
+ String[] keys = this.getKeys(beforeRow, fields);
+ Object[] values = VOEntityUtil.getVOValues(beforeRow, keys);
+ String key = StringUtil.mergeString(values, null, null);
+ List errRows = new ArrayList();
+ for (TransformBodyVO vo : afterRows) {
+ Object[] afterValues = VOEntityUtil.getVOValues(vo, keys);
+ String afterKey = StringUtil.mergeString(afterValues, null, null);
+ if (StringUtil.isStringEqual(key, afterKey)) {
+ errRows.add(vo.getCrowno());
+ }
+ }
+ return errRows;
+
+ }
+
+ /**
+ * 方法功能描述:
+ *
+ * 物料是否库存状态管理 参数说明
+ *
+ * @param cmaterialvid
+ * @return
+ *
+ * @since 6.0
+ * @author chennn
+ * @time 2010-6-1 下午04:21:39
+ */
+ private boolean isInvStateManage(String cmaterialvid, ICBSContext context) {
+ UFBoolean fix1 = context.getInvInfo().getInvBasVO(cmaterialvid).getFix1();
+ return fix1 == null ? false : fix1.booleanValue();
+
+ }
+
+ /**
+ * 方法功能描述:
+ *
+ * 物料是否勾选项目辅助属性 参数说明
+ *
+ * @param cmaterialvid
+ * @return
+ *
+ * @since 6.0
+ * @author chennn
+ * @time 2010-6-1 下午02:24:29
+ */
+ private boolean isProjectChosen(String cmaterialvid, ICBSContext context) {
+ UFBoolean fix2 = context.getInvInfo().getInvBasVO(cmaterialvid).getFix2();
+ return fix2 == null ? false : fix2.booleanValue();
+ }
+
+ /**
+ * 方法功能描述:
+ *
+ * 物料是否勾选特征码辅助属性 参数说明
+ *
+ * @param cmaterialvid
+ * @return
+ *
+ * @since 6.36
+ * @author xuxq3
+ * @time 2015-04-06
+ */
+ private boolean isCffileidChosen(String cmaterialvid, ICBSContext context) {
+ UFBoolean fix100 = context.getInvInfo().getInvBasVO(cmaterialvid).getFix100();
+ return fix100 == null ? false : fix100.booleanValue();
+ }
+
+ /**
+ * 是否勾选客户辅助属性
+ *
+ * @param cmaterialvid
+ * @param context
+ * @return
+ */
+ private boolean isCasscustChosen(String cmaterialvid, ICBSContext context) {
+ UFBoolean fix5 = context.getInvInfo().getInvBasVO(cmaterialvid).getFix5();
+ return fix5 == null ? false : fix5.booleanValue();
+ }
+
+ /**
+ * 方法功能描述:
+ *
+ * 物料是否勾选供应商辅助属性 参数说明
+ *
+ * @param cmaterialvid
+ * @return
+ *
+ * @since 6.0
+ * @author chennn
+ * @time 2010-6-1 上午10:46:09
+ */
+ private boolean isVendorChosen(String cmaterialvid, ICBSContext context) {
+ UFBoolean fix3 = context.getInvInfo().getInvBasVO(cmaterialvid).getFix3();
+ return fix3 == null ? false : fix3.booleanValue();
+ }
+
+ /**
+ * 方法功能描述:
+ *
+ * 物料是否勾选生产厂商辅助属性 参数说明
+ *
+ * @param cmaterialvid
+ * @return
+ *
+ * @since 6.0
+ * @author chennn
+ * @time 2010-6-1 下午02:24:11
+ */
+ private boolean isProductorChosen(String cmaterialvid, ICBSContext context) {
+ UFBoolean fix4 = context.getInvInfo().getInvBasVO(cmaterialvid).getFix4();
+ return fix4 == null ? false : fix4.booleanValue();
+ }
+
+ private void showItemSameErr(Map> errInfo) throws BusinessException {
+ if (errInfo.size() <= 0) {
+ return;
+ }
+ StringBuilder errMsg = new StringBuilder();
+ errMsg.append(InvAdjustRes.getBeforeSameAfterErr()).append("\n");
+ for (Map.Entry> err : errInfo.entrySet()) {
+ String beforeRowNo = err.getKey().getCrowno();
+ errMsg.append(InvAdjustRes.getBeforeRow() + beforeRowNo).append(" ");
+ for (String afterRow : err.getValue()) {
+ errMsg.append(InvAdjustRes.getAfterRow()).append(afterRow).append(",");
+ }
+ }
+
+ throw new BusinessException(errMsg.toString());
+ }
+
+}