From fd69e727ec51964335d08768b769b91cb497ecea Mon Sep 17 00:00:00 2001 From: xuhaihui <2098865055@qq.com> Date: Thu, 18 Sep 2025 18:41:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=87=BA=E5=BA=93=E5=8D=95=E6=8F=90=E4=BA=A4?= =?UTF-8?q?=E6=92=A4=E9=94=80=E7=94=9F=E6=88=90=E5=8D=B3=E6=97=B6=E5=BA=93?= =?UTF-8?q?=E5=AD=98=E9=80=BB=E8=BE=91=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../form/MaterialInventoryUtilsExt.java | 442 ++++++++++++++++++ .../plugin/operate/MaterialOutBillOpExt.java | 28 +- 2 files changed, 457 insertions(+), 13 deletions(-) create mode 100644 code/zcdev/zcgj-zcdev-zcdev-pr/src/main/java/zcgj/zcdev/zcdev/pr/plugin/form/MaterialInventoryUtilsExt.java diff --git a/code/zcdev/zcgj-zcdev-zcdev-pr/src/main/java/zcgj/zcdev/zcdev/pr/plugin/form/MaterialInventoryUtilsExt.java b/code/zcdev/zcgj-zcdev-zcdev-pr/src/main/java/zcgj/zcdev/zcdev/pr/plugin/form/MaterialInventoryUtilsExt.java new file mode 100644 index 0000000..28174e5 --- /dev/null +++ b/code/zcdev/zcgj-zcdev-zcdev-pr/src/main/java/zcgj/zcdev/zcdev/pr/plugin/form/MaterialInventoryUtilsExt.java @@ -0,0 +1,442 @@ +// +// Source code recreated from a .class file by IntelliJ IDEA +// (powered by FernFlower decompiler) +// +package zcgj.zcdev.zcdev.pr.plugin.form; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import kd.bos.dataentity.entity.DynamicObject; +import kd.bos.dataentity.metadata.dynamicobject.DynamicObjectType; +import kd.bos.dataentity.resource.ResManager; +import kd.bos.dataentity.utils.StringUtils; +import kd.bos.dlock.DLock; +import kd.bos.dlock.DLockInfo; +import kd.bos.entity.EntityMetadataCache; +import kd.bos.exception.KDBizException; +import kd.bos.logging.Log; +import kd.bos.logging.LogFactory; +import kd.bos.orm.query.QFilter; +import kd.bos.servicehelper.BusinessDataServiceHelper; +import kd.bos.servicehelper.operation.SaveServiceHelper; +import kd.ec.basedata.common.utils.CurrencyHelper; +import kd.ec.basedata.common.utils.EcNumberHelper; +import kd.ec.material.common.utils.MaterialInventoryUtils; + +public class MaterialInventoryUtilsExt { + private static final Log log = LogFactory.getLog(MaterialInventoryUtilsExt.class); + public static final DynamicObjectType matInvDT = EntityMetadataCache.getDataEntityType("ecma_matinventory"); + public static final String MatInv_Lot = "lot"; + public static final String MatInv_Price = "price"; + public static final String MatInv_Qty = "qty"; + public static final String MatInv_Amount = "amount"; + public static final String MatInv_Lockedqty = "lockedqty"; + public static final String MatInv_Tempqty = "tempqty"; + public static final String MatInv_Modelnum = "modelnum"; + public static final String MatInv_Project = "project"; + public static final String MatInv_Org = "org"; + public static final String MatInv_Material = "material"; + public static final String MatInv_Warehouse = "warehouse"; + public static final String MatInv_Measureunit = "measureunit"; + public static final String MatInv_Currency = "currency"; + public static final String selProperty = "id,measureunit,lot,currency,price,qty,amount,lockedqty,tempqty,modelnum,saleprice,measureuint,project,org,material,warehouse"; + + private MaterialInventoryUtilsExt() { + } + + public static void matBalanceUpdate(String orgId, String projectId, String warehouseId, DynamicObject[] entrys, boolean isAdd, BigDecimal exchangerate) { + matBalanceUpdateNoDLock(orgId, projectId, warehouseId, entrys, isAdd, exchangerate); + } + + public static void matBalanceLockAndUpdate(String orgId, String projectId, String warehouseId, DynamicObject[] entrys, boolean isAdd, BigDecimal exchangerate, boolean isLocked) { + String lockKey = String.format("ec/ecma/inventory_lock_%1$s_%2$s", projectId, warehouseId); + String lockDesc = String.format(ResManager.loadKDString("即时库存分布式锁_%1$s_%2$s", "MaterialInventoryUtils_14", "ec-ecma-common", new Object[0]), projectId, warehouseId); + DLock lock = DLock.create(lockKey, lockDesc).fastMode(); + boolean tryLock = lock.tryLock(50000L); + if (!tryLock) { + throw new KDBizException(ResManager.loadKDString("获取锁失败,请联系管理员。", "MaterialInventoryUtils_15", "ec-ecma-common", new Object[0])); + } else { + try { + DLockInfo lockInfo = DLock.getLockInfo(lockKey); + if (lockInfo != null) { + log.info(lockInfo.toString()); + } + + matBalanceLockedNoDLock(orgId, projectId, warehouseId, entrys, isLocked); + matBalanceUpdateNoDLock(orgId, projectId, warehouseId, entrys, isAdd, exchangerate); + } finally { + try { + lock.unlock(); + } catch (Throwable var17) { + log.info(String.format("ecma_lock %1$s unlock error :%2$s", lockKey, var17)); + } + + } + + } + } + + private static void matBalanceUpdateNoDLock(String orgId, String projectId, String warehouseId, DynamicObject[] entrys, boolean isAdd, BigDecimal exchangerate) { + BigDecimal coef = BigDecimal.ONE; + if (!isAdd) { + coef = BigDecimal.valueOf(-1L); + } + + List mergedFields = new ArrayList(); + mergedFields.add("qty"); + mergedFields.add("amount"); + if (entrys.length > 0 && entrys[0].getDataEntityType().getProperties().containsKey("ftransamount")) { + mergedFields.add("ftransamount"); + } + + DynamicObject[] mergedEntrys = mergeSameMaterial(entrys, mergedFields); + Set materialIdSet = new HashSet(); + DynamicObject[] var10 = mergedEntrys; + int var11 = mergedEntrys.length; + + for(int var12 = 0; var12 < var11; ++var12) { + DynamicObject mergedEntry = var10[var12]; + Long materialId = mergedEntry.getLong("material_id"); + if (materialId != null && materialId != 0L) { + materialIdSet.add(materialId); + } + } + + QFilter filter = new QFilter("org", "=", StringUtils.isBlank(orgId) ? 0L : Long.parseLong(orgId)); + filter.and(new QFilter("project", "=", StringUtils.isBlank(projectId) ? 0L : Long.parseLong(projectId))); + filter.and(new QFilter("warehouse", "=", StringUtils.isBlank(warehouseId) ? 0L : Long.parseLong(warehouseId))); + QFilter materialIdFilter = new QFilter("material", "in", materialIdSet); + DynamicObject[] ecmaMatinventories = BusinessDataServiceHelper.load("ecma_matinventory", "id,measureunit,lot,currency,price,qty,amount,lockedqty,tempqty,modelnum,saleprice,measureuint,project,org,material,warehouse", new QFilter[]{filter, materialIdFilter}); + Map matInventoryMap = new HashMap(); + DynamicObject[] var33 = ecmaMatinventories; + int i = ecmaMatinventories.length; + + String matId; + String modelnum; + String lot; + String unitId; + String key; + for(int var16 = 0; var16 < i; ++var16) { + DynamicObject ecmaMatinventory = var33[var16]; + matId = ecmaMatinventory.getDynamicObject("material").getString("id"); + modelnum = "".equals(ecmaMatinventory.getString("modelnum")) ? " " : ecmaMatinventory.getString("modelnum"); + lot = "".equals(ecmaMatinventory.getString("lot")) ? " " : ecmaMatinventory.getString("lot"); + unitId = ecmaMatinventory.getDynamicObject("measureunit") == null ? "" : ecmaMatinventory.getDynamicObject("measureunit").getString("id"); + key = String.format("%1$s_%2$s_%3$s_%4$s", matId, modelnum, lot, unitId); + matInventoryMap.put(key, ecmaMatinventory); + } + + List matInvList = new ArrayList(); + + for(i = 0; i < mergedEntrys.length; ++i) { + DynamicObject entryInfo = mergedEntrys[i]; + boolean isFirst = false; + matId = entryInfo.getDynamicObject("material").getString("id"); + modelnum = "".equals(entryInfo.getString("modelnum")) ? " " : entryInfo.getString("modelnum"); + lot = "".equals(entryInfo.getString("lot")) ? " " : entryInfo.getString("lot"); + unitId = entryInfo.getDynamicObject("measureunit") == null ? "" : entryInfo.getDynamicObject("measureunit").getString("id"); + key = String.format("%1$s_%2$s_%3$s_%4$s", matId, modelnum, lot, unitId); + DynamicObject matInvInfo = (DynamicObject)matInventoryMap.get(key); + BigDecimal qty; + if (matInvInfo == null || BigDecimal.ZERO.compareTo(matInvInfo.getBigDecimal("tempqty")) == 0) { + if (entryInfo.getDataEntityType().getProperties().containsKey("ftransamount")) { + qty = entryInfo.getBigDecimal("ftransamount"); + if (BigDecimal.ZERO.compareTo(qty) == 0) { + isFirst = true; + } + } else { + isFirst = true; + } + } + + if (matInvInfo == null) { + matInvInfo = setMatInvInfo(orgId, projectId, warehouseId, entryInfo, coef, exchangerate); + } else { + qty = entryInfo.getBigDecimal("qty").multiply(coef); + BigDecimal amount = entryInfo.getBigDecimal("amount").multiply(exchangerate); + amount = amount.multiply(coef); + BigDecimal totalQty = matInvInfo.getBigDecimal("qty"); + BigDecimal totalTmpQty = matInvInfo.getBigDecimal("tempqty"); + if (BigDecimal.ZERO.compareTo(totalTmpQty) == 0) { + matInvInfo.set("price", entryInfo.getBigDecimal("price").multiply(exchangerate)); + } + + totalQty = EcNumberHelper.add(totalQty, qty); + BigDecimal totalAmount = matInvInfo.getBigDecimal("amount"); + totalAmount = EcNumberHelper.add(totalAmount, amount); + totalTmpQty = EcNumberHelper.add(totalTmpQty, qty); + matInvInfo.set("qty", totalQty); + matInvInfo.set("tempqty", totalTmpQty); + matInvInfo.set("amount", totalAmount); + if (!isFirst && totalQty.compareTo(BigDecimal.ZERO) != 0) { + matInvInfo.set("price", totalAmount.divide(totalTmpQty, 10, 4)); + } + } + + matInvList.add(matInvInfo); + } + + if (!matInvList.isEmpty()) { + SaveServiceHelper.save((DynamicObject[])matInvList.toArray(new DynamicObject[0])); + } + + } + + private static String matBalanceLockedNoDLock(String orgId, String projectId, String warehouseId, DynamicObject[] entrys, boolean isLocked) { + BigDecimal coef = BigDecimal.ONE; + if (!isLocked) { + coef = BigDecimal.valueOf(-1L); + } + + // 使用Map来按物料唯一标识分组并累加qty + Map materialQtyMap = new HashMap<>(); + Map materialEntryMap = new HashMap<>(); + Map materialInvMap = new HashMap<>(); + + // 第一次循环:累加相同物料的qty + for (DynamicObject entryInfo : entrys) { + DynamicObject material = entryInfo.getDynamicObject("material"); + String matId = material.getString("id"); + String modelnum = "".equals(entryInfo.getString("modelnum")) ? " " : entryInfo.getString("modelnum"); + String lot = "".equals(entryInfo.getString("lot")) ? " " : entryInfo.getString("lot"); + String unitId = entryInfo.getDynamicObject("measureunit") == null ? "" : entryInfo.getDynamicObject("measureunit").getString("id"); + + // 创建物料的唯一键 + String materialKey = matId + "|" + modelnum + "|" + lot + "|" + unitId; + + // 累加qty + BigDecimal currentQty = entryInfo.getBigDecimal("qty").multiply(coef); + materialQtyMap.merge(materialKey, currentQty, BigDecimal::add); + + // 保存entryInfo和material信息供后续使用 + materialEntryMap.put(materialKey, entryInfo); + materialInvMap.put(materialKey, material); + } + + List matInvList = new ArrayList<>(); + + // 第二次循环:处理累加后的qty + for (Map.Entry entry : materialQtyMap.entrySet()) { + String materialKey = entry.getKey(); + String[] keys = materialKey.split("\\|"); + String matId = keys[0]; + String modelnum = keys[1]; + String lot = keys[2]; + String unitId = keys[3]; + + DynamicObject entryInfo = materialEntryMap.get(materialKey); + DynamicObject material = materialInvMap.get(materialKey); + String unitName = entryInfo.getDynamicObject("measureunit") == null ? "" : entryInfo.getDynamicObject("measureunit").getString("name"); + + DynamicObject matInvInfo = getMatInvInfo(orgId, projectId, warehouseId, matId, modelnum, lot, unitId); + if (matInvInfo == null) { + String errMsg = String.format(ResManager.loadKDString("编码为%1$s,名称为%2$s,规格型号为%3$s,计量单位为%4$s,批次为%5$s的物料无法在即时库存中找到", "MaterialInventoryUtils_11", "ec-ecma-common", new Object[0]), + material.getString("number"), material.getString("name"), modelnum, unitName, lot); + return errMsg; + } + + BigDecimal totalQtyChange = entry.getValue(); // 这是累加后的qty + BigDecimal totalLockedQty = matInvInfo.getBigDecimal("lockedqty"); + BigDecimal totalQty = matInvInfo.getBigDecimal("qty"); + + totalLockedQty = EcNumberHelper.add(totalLockedQty, totalQtyChange); + totalQty = EcNumberHelper.subtract(totalQty, totalQtyChange); + + matInvInfo.set("lockedqty", totalLockedQty); + matInvInfo.set("qty", totalQty); + matInvList.add(matInvInfo); + } + + if (!matInvList.isEmpty()) { + SaveServiceHelper.save(((DynamicObject)matInvList.get(0)).getDataEntityType(), matInvList.toArray(new DynamicObject[0])); + } + + return "success"; + } + + public static String matBalanceLocked(String orgId, String projectId, String warehouseId, DynamicObject[] entrys, boolean isLocked) { + return matBalanceLockedNoDLock(orgId, projectId, warehouseId, entrys, isLocked); + } + + public static DynamicObject[] mergeSameMaterial(DynamicObject[] entrys, List mergeFields) { + if (entrys != null && entrys.length > 0) { + List dimensionList = new ArrayList(); + dimensionList.add("material"); + dimensionList.add("modelnum"); + dimensionList.add("lot"); + dimensionList.add("measureunit"); + dimensionList.add("price"); + List copiedList = new ArrayList(); + + for(int i = 0; i < entrys.length; ++i) { + DynamicObject entryInfo = entrys[i]; + DynamicObject copiedObj = new DynamicObject(entrys[0].getDynamicObjectType()); + if (copiedList.isEmpty()) { + dimensionList.forEach((dimension) -> { + copiedObj.set(dimension, entryInfo.get(dimension)); + }); + mergeFields.forEach((field) -> { + copiedObj.set(field, entryInfo.get(field)); + }); + copiedList.add(copiedObj); + } else { + String matId = entryInfo.getDynamicObject("material").getString("id"); + String modelnum = "".equals(entryInfo.getString("modelnum")) ? " " : entryInfo.getString("modelnum"); + String lot = entryInfo.getString("lot"); + String unitId = entryInfo.getDynamicObject("measureunit") == null ? "" : entryInfo.getDynamicObject("measureunit").getString("id"); + List sameList = (List)copiedList.stream().filter((obj) -> { + return matId.equals(obj.getDynamicObject("material").getString("id")) && modelnum.equals(obj.getString("modelnum") != null && !"".equals(obj.getString("modelnum")) ? obj.getString("modelnum") : " ") && unitId.equals(obj.getDynamicObject("measureunit") == null ? "" : obj.getDynamicObject("measureunit").getString("id")) && lot.equals(obj.getString("lot")); + }).collect(Collectors.toList()); + if (sameList.isEmpty()) { + dimensionList.forEach((dimension) -> { + copiedObj.set(dimension, entryInfo.get(dimension)); + }); + mergeFields.forEach((field) -> { + copiedObj.set(field, entryInfo.get(field)); + }); + copiedList.add(copiedObj); + } else { + DynamicObject mergedMatInfo = (DynamicObject)sameList.get(0); + mergeFields.forEach((field) -> { + mergedMatInfo.set(field, EcNumberHelper.add(mergedMatInfo.getBigDecimal(field), entryInfo.getBigDecimal(field))); + }); + BigDecimal qty = mergedMatInfo.getBigDecimal("qty"); + BigDecimal price = qty != null && qty.compareTo(BigDecimal.ZERO) != 0 ? mergedMatInfo.getBigDecimal("amount").divide(qty, 10, 4) : BigDecimal.ZERO; + mergedMatInfo.set("price", price); + } + } + } + + return (DynamicObject[])copiedList.toArray(new DynamicObject[0]); + } else { + return new DynamicObject[0]; + } + } + + public static String checkMatAsOut(String orgId, String projectId, String warehouseId, DynamicObject[] entrys) { + List mergedFields = new ArrayList(); + mergedFields.add("qty"); + DynamicObject[] mergedEntrys = mergeSameMaterial(entrys, mergedFields); + + for(int i = 0; i < mergedEntrys.length; ++i) { + DynamicObject entryInfo = mergedEntrys[i]; + DynamicObject material = entryInfo.getDynamicObject("material"); + String matId = material.getString("id"); + String modelnum = "".equals(entryInfo.getString("modelnum")) ? " " : entryInfo.getString("modelnum"); + String lot = "".equals(entryInfo.getString("lot")) ? " " : entryInfo.getString("lot"); + String unitId = entryInfo.getDynamicObject("measureunit") == null ? "" : entryInfo.getDynamicObject("measureunit").getString("id"); + BigDecimal outQty = entryInfo.getBigDecimal("qty"); + DynamicObject matInvInfo = getMatInvInfo(orgId, projectId, warehouseId, matId, modelnum, lot, unitId); + String unitName = entryInfo.getDynamicObject("measureunit") == null ? "" : entryInfo.getDynamicObject("measureunit").getString("name"); + if (matInvInfo == null) { + String errMsg = String.format(ResManager.loadKDString("编码为%1$s,名称为%2$s,规格型号为%3$s,计量单位为%4$s,批次为%5$s的物料无法在即时库存中找到", "MaterialInventoryUtils_11", "ec-ecma-common", new Object[0]), material.getString("number"), material.getString("name"), " ".equals(modelnum) ? ResManager.loadKDString("空", "MaterialInventoryUtils_2", "ec-ecma-common", new Object[0]) : modelnum, "".equals(unitName) ? ResManager.loadKDString("空", "MaterialInventoryUtils_2", "ec-ecma-common", new Object[0]) : unitName, " ".equals(lot) ? ResManager.loadKDString("空", "MaterialInventoryUtils_2", "ec-ecma-common", new Object[0]) : lot); + return errMsg; + } + + BigDecimal invQty = matInvInfo.getBigDecimal("qty"); + if (outQty.compareTo(invQty) > 0) { + return String.format(ResManager.loadKDString("编码为%1$s,名称为%2$s,规格型号为%3$s,计量单位为%4$s,批次为%5$s的物料库存不足。", "MaterialInventoryUtils_12", "ec-ecma-common", new Object[0]), material.getString("number"), material.getString("name"), " ".equals(modelnum) ? ResManager.loadKDString("空", "MaterialInventoryUtils_2", "ec-ecma-common", new Object[0]) : modelnum, "".equals(unitName) ? ResManager.loadKDString("空", "MaterialInventoryUtils_2", "ec-ecma-common", new Object[0]) : unitName, " ".equals(lot) ? ResManager.loadKDString("空", "MaterialInventoryUtils_2", "ec-ecma-common", new Object[0]) : lot); + } + } + + return "success"; + } + + public static String checkInventoryQty(String orgId, String projectId, String warehouseId, DynamicObject[] entrys) { + List mergedFields = new ArrayList(); + mergedFields.add("qty"); + DynamicObject[] mergedEntrys = mergeSameMaterial(entrys, mergedFields); + + for(int i = 0; i < mergedEntrys.length; ++i) { + DynamicObject entryInfo = mergedEntrys[i]; + DynamicObject material = entryInfo.getDynamicObject("material"); + String matId = material.getString("id"); + String modelnum = "".equals(entryInfo.getString("modelnum")) ? " " : entryInfo.getString("modelnum"); + String lot = "".equals(entryInfo.getString("lot")) ? " " : entryInfo.getString("lot"); + String unitId = entryInfo.getDynamicObject("measureunit") == null ? "" : entryInfo.getDynamicObject("measureunit").getString("id"); + BigDecimal outQty = entryInfo.getBigDecimal("qty"); + DynamicObject matInvInfo = getMatInvInfo(orgId, projectId, warehouseId, matId, modelnum, lot, unitId); + String unitName = entryInfo.getDynamicObject("measureunit") == null ? "" : entryInfo.getDynamicObject("measureunit").getString("name"); + if (matInvInfo == null) { + String errMsg = String.format(ResManager.loadKDString("编码为%1$s,名称为%2$s,规格型号为%3$s,计量单位为%4$s,批次为%5$s的物料无法在即时库存中找到", "MaterialInventoryUtils_11", "ec-ecma-common", new Object[0]), material.getString("number"), material.getString("name"), " ".equals(modelnum) ? ResManager.loadKDString("空", "MaterialInventoryUtils_2", "ec-ecma-common", new Object[0]) : modelnum, "".equals(unitName) ? ResManager.loadKDString("空", "MaterialInventoryUtils_2", "ec-ecma-common", new Object[0]) : unitName, " ".equals(lot) ? ResManager.loadKDString("空", "MaterialInventoryUtils_2", "ec-ecma-common", new Object[0]) : lot); + return errMsg; + } + + BigDecimal invQty = matInvInfo.getBigDecimal("qty"); + if (invQty.compareTo(BigDecimal.ZERO) < 0 && outQty.compareTo(BigDecimal.ZERO) > 0) { + String errMsg = String.format(ResManager.loadKDString("编码为%1$s,名称为%2$s,规格型号为%3$s,计量单位为%4$s,批次为%5$s的物料库存不足。", "MaterialInventoryUtils_12", "ec-ecma-common", new Object[0]), material.getString("number"), material.getString("name"), " ".equals(modelnum) ? ResManager.loadKDString("空", "MaterialInventoryUtils_2", "ec-ecma-common", new Object[0]) : modelnum, "".equals(unitName) ? ResManager.loadKDString("空", "MaterialInventoryUtils_2", "ec-ecma-common", new Object[0]) : unitName, " ".equals(lot) ? ResManager.loadKDString("空", "MaterialInventoryUtils_2", "ec-ecma-common", new Object[0]) : lot); + return errMsg; + } + } + + return "success"; + } + + private static DynamicObject setMatInvInfo(String orgId, String projectId, String warehouseId, DynamicObject entryInfo, BigDecimal coef, BigDecimal exchangerate) { + DynamicObject matInf = BusinessDataServiceHelper.loadSingle("ecma_matinventory", "id,measureunit,lot,currency,price,qty,amount,lockedqty,tempqty,modelnum,saleprice,measureuint,project,org,material,warehouse", new QFilter[]{new QFilter("id", "!=", 0)}); + DynamicObject matInvInfo; + if (matInf != null) { + matInvInfo = new DynamicObject(matInf.getDynamicObjectType()); + } else { + matInvInfo = new DynamicObject(matInvDT); + } + + matInvInfo.set("org", orgId); + matInvInfo.set("project", projectId); + matInvInfo.set("warehouse", warehouseId); + matInvInfo.set("material", entryInfo.getDynamicObject("material").getString("id")); + matInvInfo.set("lot", entryInfo.getString("lot")); + matInvInfo.set("measureunit", entryInfo.getDynamicObject("measureunit")); + matInvInfo.set("currency", CurrencyHelper.getCurrency(Long.valueOf(orgId))); + matInvInfo.set("price", entryInfo.getBigDecimal("price").multiply(exchangerate)); + matInvInfo.set("qty", entryInfo.getBigDecimal("qty").multiply(coef)); + matInvInfo.set("amount", entryInfo.getBigDecimal("amount").multiply(coef).multiply(exchangerate)); + matInvInfo.set("tempqty", entryInfo.getBigDecimal("qty").multiply(coef)); + matInvInfo.set("modelnum", entryInfo.getString("modelnum")); + return matInvInfo; + } + + private static DynamicObject getMatInvInfo(String orgId, String projectId, String warehouseId, String matId, String modelnum, String lot, String unitId) { + QFilter filter = new QFilter("org", "=", StringUtils.isBlank(orgId) ? 0L : Long.parseLong(orgId)); + filter.and(new QFilter("project", "=", StringUtils.isBlank(projectId) ? 0L : Long.parseLong(projectId))); + filter.and(new QFilter("warehouse", "=", StringUtils.isBlank(warehouseId) ? 0L : Long.parseLong(warehouseId))); + filter.and(new QFilter("material", "=", StringUtils.isBlank(matId) ? 0L : Long.parseLong(matId))); + filter.and(new QFilter("modelnum", "=", modelnum == "" ? " " : modelnum)); + filter.and(new QFilter("lot", "=", lot)); + filter.and(new QFilter("measureunit", "=", StringUtils.isBlank(unitId) ? 0L : Long.parseLong(unitId))); + DynamicObject matInvInfo = BusinessDataServiceHelper.loadSingle("ecma_matinventory", "id,measureunit,lot,currency,price,qty,amount,lockedqty,tempqty,modelnum,saleprice,measureuint,project,org,material,warehouse", new QFilter[]{filter}); + return matInvInfo; + } + + public static String[] getEntryKeys() { + return new String[]{"materialId", "modelnum", "lot"}; + } + + public static String checkLotPrice(String orgId, String projectId, String warehouseId, DynamicObject[] entrys) { + for(int i = 0; i < entrys.length; ++i) { + DynamicObject entryInfo = entrys[i]; + String lot = entryInfo.getString("lot"); + if (lot != null && lot != "") { + DynamicObject material = entryInfo.getDynamicObject("material"); + String matId = material.getString("id"); + String modelnum = "".equals(entryInfo.getString("modelnum")) ? " " : entryInfo.getString("modelnum"); + BigDecimal outPrice = entryInfo.getBigDecimal("price"); + String unitId = entryInfo.getDynamicObject("measureunit") == null ? "" : entryInfo.getDynamicObject("measureunit").getString("id"); + DynamicObject invMatInfo = getMatInvInfo(orgId, projectId, warehouseId, matId, modelnum, lot, unitId); + BigDecimal invPrice = invMatInfo.getBigDecimal("price"); + if (outPrice.compareTo(invPrice) != 0) { + String errMsg = String.format(ResManager.loadKDString("编码为%1$s,名称为%2$s,,规格型号为%3$s,批次为%4$s的物料存在批次且出库价格跟入库价格不一致!", "MaterialInventoryUtils_13", "ec-ecma-common", new Object[0]), material.getString("number"), material.getString("name"), modelnum, lot); + return errMsg; + } + } + } + + return "success"; + } +} diff --git a/code/zcdev/zcgj-zcdev-zcdev-pr/src/main/java/zcgj/zcdev/zcdev/pr/plugin/operate/MaterialOutBillOpExt.java b/code/zcdev/zcgj-zcdev-zcdev-pr/src/main/java/zcgj/zcdev/zcdev/pr/plugin/operate/MaterialOutBillOpExt.java index c706879..d53d4c7 100644 --- a/code/zcdev/zcgj-zcdev-zcdev-pr/src/main/java/zcgj/zcdev/zcdev/pr/plugin/operate/MaterialOutBillOpExt.java +++ b/code/zcdev/zcgj-zcdev-zcdev-pr/src/main/java/zcgj/zcdev/zcdev/pr/plugin/operate/MaterialOutBillOpExt.java @@ -40,6 +40,7 @@ import kd.ec.material.common.utils.MaterialInventoryUtils; import kd.ec.material.opplugin.validator.InvAdjustBillExistValidator; import kd.ec.material.opplugin.validator.MaterialOutBillValidator; import org.apache.commons.collections4.CollectionUtils; +import zcgj.zcdev.zcdev.pr.plugin.form.MaterialInventoryUtilsExt; /* * 出库单提交撤销和审核反审核操作系统插件 @@ -155,9 +156,9 @@ public class MaterialOutBillOpExt extends AbstractOperationServicePlugIn { } if ("INCREASE".equals(type)) { - MaterialInventoryUtils.matBalanceUpdate(orgId, projectId, warehouseId, (DynamicObject[])entryCol.toArray(new DynamicObject[entryCol.size()]), true, exchangerate); + MaterialInventoryUtilsExt.matBalanceUpdate(orgId, projectId, warehouseId, (DynamicObject[])entryCol.toArray(new DynamicObject[entryCol.size()]), true, exchangerate); } else if ("REDUCE".equals(type)) { - MaterialInventoryUtils.matBalanceLockAndUpdate(orgId, projectId, warehouseId, (DynamicObject[])entryCol.toArray(new DynamicObject[entryCol.size()]), false, exchangerate, false); + MaterialInventoryUtilsExt.matBalanceLockAndUpdate(orgId, projectId, warehouseId, (DynamicObject[])entryCol.toArray(new DynamicObject[entryCol.size()]), false, exchangerate, false); } } @@ -194,9 +195,9 @@ public class MaterialOutBillOpExt extends AbstractOperationServicePlugIn { } if ("INCREASE".equals(type)) { - MaterialInventoryUtils.matBalanceUpdate(orgId, projectId, warehouseId, (DynamicObject[])entryCol.toArray(new DynamicObject[entryCol.size()]), false, exchangerate); + MaterialInventoryUtilsExt.matBalanceUpdate(orgId, projectId, warehouseId, (DynamicObject[])entryCol.toArray(new DynamicObject[entryCol.size()]), false, exchangerate); } else if ("REDUCE".equals(type)) { - MaterialInventoryUtils.matBalanceUpdate(orgId, projectId, warehouseId, (DynamicObject[])entryCol.toArray(new DynamicObject[entryCol.size()]), true, exchangerate); + MaterialInventoryUtilsExt.matBalanceUpdate(orgId, projectId, warehouseId, (DynamicObject[])entryCol.toArray(new DynamicObject[entryCol.size()]), true, exchangerate); } } } @@ -238,7 +239,8 @@ public class MaterialOutBillOpExt extends AbstractOperationServicePlugIn { QFilter qFilter = new QFilter("billno", "=", billNumber); qFilter.and(new QFilter("matbilltype", "=", "materialout")); qFilter.and(new QFilter("billstatus", "in", new String[]{"B", "C"})); - DynamicObject[] materialOutBills = BusinessDataServiceHelper.load("ecma_materialoutbill", "billno,matbilltype", new QFilter[]{qFilter}); + DynamicObject[] materialOutBills = BusinessDataServiceHelper.load("ecma_materialoutbill", + "billno,matbilltype", new QFilter[]{qFilter});//出库单 if (materialOutBills != null && materialOutBills.length > 0) { projectId = String.format(ResManager.loadKDString("单据编码%s重复,请重新输入单据编码!", "MaterialOutBillOp_0", "ec-ecma-opplugin", new Object[0]), billNumber); throw new KDBizException(projectId); @@ -276,16 +278,16 @@ public class MaterialOutBillOpExt extends AbstractOperationServicePlugIn { } } - DynamicObjectCollection entryCol1 = obj.getDynamicObjectCollection("entryentity"); - DynamicObject transType1 = obj.getDynamicObject("transtype"); - String type1 = transType1.getString("type");//注释掉系统标准代码 + DynamicObjectCollection entryCol1 = obj.getDynamicObjectCollection("entryentity");//出库单分录 + DynamicObject transType1 = obj.getDynamicObject("transtype");//事务类型 + String type1 = transType1.getString("type");//事务类型-库存数量影响类型为减 if ("REDUCE".equals(type1)) { - String msg1 = MaterialInventoryUtils.checkMatAsOut(orgId, projectId, warehouseId, (DynamicObject[])entryCol1.toArray(new DynamicObject[entryCol1.size()])); + String msg1 = MaterialInventoryUtilsExt.checkMatAsOut(orgId, projectId, warehouseId, (DynamicObject[])entryCol1.toArray(new DynamicObject[entryCol1.size()])); if (!"success".equals(msg1)) { throw new KDBizException(msg1); } - String msg2 = MaterialInventoryUtils.matBalanceLocked(orgId, projectId, warehouseId, (DynamicObject[])entryCol1.toArray(new DynamicObject[entryCol1.size()]), true); + String msg2 = MaterialInventoryUtilsExt.matBalanceLocked(orgId, projectId, warehouseId, (DynamicObject[])entryCol1.toArray(new DynamicObject[entryCol1.size()]), true); if (!"success".equals(msg2)) { throw new KDBizException(msg2); } @@ -311,7 +313,7 @@ public class MaterialOutBillOpExt extends AbstractOperationServicePlugIn { transType = obj.getDynamicObject("transtype"); type = transType.getString("type"); if ("REDUCE".equals(type)) { - projectId = MaterialInventoryUtils.matBalanceLocked(orgId, projectId, warehouseId, (DynamicObject[])entryCol.toArray(new DynamicObject[entryCol.size()]), false); + projectId = MaterialInventoryUtilsExt.matBalanceLocked(orgId, projectId, warehouseId, (DynamicObject[])entryCol.toArray(new DynamicObject[entryCol.size()]), false); if (!"success".equals(projectId)) { throw new KDBizException(projectId); } @@ -336,7 +338,7 @@ public class MaterialOutBillOpExt extends AbstractOperationServicePlugIn { transType = obj.getDynamicObject("transtype"); type = transType.getString("type"); if ("REDUCE".equals(type)) { - projectId = MaterialInventoryUtils.checkInventoryQty(orgId, projectId, warehouseId, (DynamicObject[])entryCol.toArray(new DynamicObject[entryCol.size()])); + projectId = MaterialInventoryUtilsExt.checkInventoryQty(orgId, projectId, warehouseId, (DynamicObject[])entryCol.toArray(new DynamicObject[entryCol.size()])); if (!"success".equals(projectId)) { throw new KDBizException(projectId); } @@ -380,7 +382,7 @@ public class MaterialOutBillOpExt extends AbstractOperationServicePlugIn { type = transType.getString("type"); if ("INCREASE".equals(type)) { - String checkResult = MaterialInventoryUtils.checkMatAsOut(orgId, projectId, warehouseId, (DynamicObject[]) entryCol.toArray(new DynamicObject[entryCol.size()])); + String checkResult = MaterialInventoryUtilsExt.checkMatAsOut(orgId, projectId, warehouseId, (DynamicObject[]) entryCol.toArray(new DynamicObject[entryCol.size()])); if (!"success".equals(checkResult)) { String errMsg = String.format(ResManager.loadKDString("反审核失败,反审核后%s负库存!", "MaterialOutBillOp_6", "ec-ecma-opplugin", new Object[0]), checkResult.substring(0, checkResult.length() - 3)); throw new KDBizException(errMsg);