package com.consum.base.service; import com.consum.base.core.CodeGeneratorEnum; import com.consum.base.core.CodeGeneratorService; import com.consum.base.core.WhBusinessEnum; import com.consum.base.core.param.BaseWarehouseParam1; import com.consum.base.core.util.LockManage; import com.consum.model.po.*; import com.iplatform.model.po.S_user_core; import com.walker.infrastructure.utils.CollectionUtils; import com.walker.infrastructure.utils.DateUtils; import com.walker.infrastructure.utils.NumberGenerator; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.interceptor.TransactionAspectSupport; import javax.annotation.Resource; import java.util.List; import java.util.Map; /** * @ClassName WhFormOutputCoreService * @Author cy * @Date 2023/10/26 * @Description * @Version 1.0 **/ @Slf4j @Service public class LWhFormOutputCoreService { @Resource private BaseGoodsTemplateServiceImpl baseGoodsTemplateService; @Resource private LWhGoodsService lWhGoodsService; @Resource private CodeGeneratorService codeGeneratorService; @Resource private LWhProcureModelService lWhProcureModelService; @Resource private LWhFormTransferService lWhFormTransferService; @Resource private LWhFormOutputService lWhFormOutputService; @Resource private LWarehouseFlowService lWarehouseFlowService; /** * 根据 调拨单 生成 出库单 * * @param whFormTransferId 调拨单id * @return 出库单Id */ @Transactional(rollbackFor = Exception.class) public Long createOutFormByTransId(Long whFormTransferId, S_user_core currentUser) { if (whFormTransferId == null) { return null; } LWhFormTransfer lWhFormTransfer = new LWhFormTransfer(whFormTransferId); lWhFormTransfer = lWhFormTransferService.get(lWhFormTransfer); if (lWhFormTransfer == null || lWhFormTransfer.getStates() != 0) { log.error("调拨失败!请检查调拨单状态"); return null; } //申请调拨的物品 List goodsModelNumList = lWhProcureModelService.getModelByForm(WhBusinessEnum.DIAOBO, whFormTransferId); if (CollectionUtils.isEmpty(goodsModelNumList)) { log.error("没有要入库的物品"); return null; } Long outWarehouseId = lWhFormTransfer.getOutWarehouseId(); String outWarehouseName = lWhFormTransfer.getOutWarehouseName(); // 出库单ID Long outWarehouseFormId = NumberGenerator.getLongSequenceNumberNano(); // 调拨单物品 已经按型号分好了 goodsModelNumList.forEach(itemModelInfo -> { // 需要调拨的物品的某个型号 Long baseGoodsModelsId = itemModelInfo.getBaseGoodsModelsId(); // 需要调拨的物品某个型号的数量 Integer counts = itemModelInfo.getCounts(); //通过LockManage获得锁 //因为是根据调拨生成的 所以此处不用校验库存 // Object warehouseModelLockObj = LockManage.acquireLock(outWarehouseId, baseGoodsModelsId); // synchronized (warehouseModelLockObj) { // 获得锁后查询该型号的期初数量 // int goodsModelNum = lWhGoodsService.queryGoodsModelNum(outWarehouseId, baseGoodsModelsId, queryModelStatus, buyType); // if (goodsModelNum < counts) { // log.error("出库失败!型号{} 的数量不足,需要调拨{}个,仓库中现存{}个", baseGoodsModelsId, counts, goodsModelNum); // // 手动回滚 // TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); // throw new RuntimeException("出库失败!型号数量不足"); // } // 复用对象 itemModelInfo.setId(NumberGenerator.getLongSequenceNumber()); itemModelInfo.setFromProcureGoodsId(null); itemModelInfo.setBusinessType(3); itemModelInfo.setBusinessId(outWarehouseFormId); itemModelInfo.setPrice(null); // itemModelInfo.setCounts(counts); // itemModelInfo.setWorehouseCount(goodsModelNum); itemModelInfo.setSupplier(null); // } }); lWhProcureModelService.insertBatch(goodsModelNumList); // //创建出库单 LWhFormOutput whFormOutput = new LWhFormOutput(); whFormOutput.setId(outWarehouseFormId); // 此时并没有出库 whFormOutput.setWarehouseFlowId(null); whFormOutput.setBusinessFormCode(codeGeneratorService.createCodeByPrefix(CodeGeneratorEnum.OutPut_Warehouse.getValue(), 4)); //进出库流水总表 入库单ID whFormOutput.setInWarehouseFlowId(null); // 调拨单ID(调拨时需要) whFormOutput.setTransBusinessId(whFormTransferId); whFormOutput.setOutputCode(BaseWarehouseParam1.In_OutPutTypeEnum.Transfer_Output.getValue() + ""); whFormOutput.setOutputName("调拨出库"); whFormOutput.setWarehouseId(outWarehouseId); whFormOutput.setWarehouseName(outWarehouseName); whFormOutput.setAgencyId(null); whFormOutput.setAgencyName(null); whFormOutput.setOperatorId(currentUser.getId()); whFormOutput.setOperatorName(currentUser.getNick_name()); long dealTime = DateUtils.getDateTimeNumber(System.currentTimeMillis()); whFormOutput.setDealTime(dealTime); whFormOutput.setStates(1); int insert = lWhFormOutputService.insert(whFormOutput); if (insert == 0) { TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return null; } return outWarehouseFormId; } /** * 根据 出库单 出库 * * @param outWarehouseFormId 出库单Id * @return */ @Transactional(rollbackFor = Exception.class) public Long outFormByTransId(Long outWarehouseFormId, S_user_core currentUser) { if (outWarehouseFormId == null) { return null; } LWhFormOutput lWhFormOutput = new LWhFormOutput(outWarehouseFormId); lWhFormOutput = lWhFormOutputService.get(lWhFormOutput); if (lWhFormOutput == null || lWhFormOutput.getStates() != 1) { log.error("出库失败!请检查出库单状态"); return null; } //申请调拨的物品 List goodsModelNumList = lWhProcureModelService.getModelByForm(WhBusinessEnum.CHUKU, outWarehouseFormId); if (CollectionUtils.isEmpty(goodsModelNumList)) { log.error("没有要出库的物品"); return null; } // 要出物品的仓库id Long outWarehouseId = lWhFormOutput.getWarehouseId(); String warehouseName = lWhFormOutput.getWarehouseName(); Long userId = currentUser.getId(); String nickName = currentUser.getNick_name(); long dealTime = DateUtils.getDateTimeNumber(System.currentTimeMillis()); // 流水记录总表ID long lWarehouseFlowId = NumberGenerator.getLongSequenceNumberNano(); // 流水记录总表中 业务ID 。调拨单时 保存调拨单id 出库单时 保存出库单id long lWarehouseFlowBusinessId = outWarehouseFormId; // 物品状态(0=在途调拨;1=入库未分发;2=已下发;3=报废) short queryModelStatusT = 1; //采购方式(1:集采;2=自采) Short buyTypeT = null; String outputCode = lWhFormOutput.getOutputCode(); if ((BaseWarehouseParam1.In_OutPutTypeEnum.Transfer_Output.getValue() + "").equals(outputCode)) { //调拨出库 queryModelStatusT = 1; buyTypeT = 1; lWarehouseFlowBusinessId = lWhFormOutput.getTransBusinessId(); } else if ((BaseWarehouseParam1.In_OutPutTypeEnum.Dept_Lending_Out.getValue() + "").equals(outputCode)) { // 部门仓库 分发出库 // queryModelStatusT = 2; } short queryModelStatus = queryModelStatusT; Short buyType = buyTypeT; goodsModelNumList.forEach(itemModelInfo -> { // 需要调拨的物品的某个型号 Long baseGoodsModelsId = itemModelInfo.getBaseGoodsModelsId(); // 需要调拨的物品某个型号的数量 Integer counts = itemModelInfo.getCounts(); //查询型号信息 Map tempGoodsInfo = baseGoodsTemplateService.queryGoodsInfoByModelId(baseGoodsModelsId); //价值类型 String classificationObj = (String) tempGoodsInfo.get("classification"); Short classificationT = 3; if (classificationObj != null) { classificationT = (short) ((classificationObj).charAt(0) - 64); } short classification = classificationT; Long tempGoodsId = (Long) tempGoodsInfo.get("goodsid"); String goodsName = (String) tempGoodsInfo.get("goodsname"); String modelName = (String) tempGoodsInfo.get("modelname"); String goodsUnit = (String) tempGoodsInfo.get("unit"); // 插入 各规格物品的进出库记录 L_WH_GOODS_RECORD long whGoodsRecordId = NumberGenerator.getLongSequenceNumberNano(); LWhGoodsRecord whGoodsRecord = new LWhGoodsRecord(); whGoodsRecord.setId(whGoodsRecordId); whGoodsRecord.setWarehouseId(outWarehouseId); whGoodsRecord.setWarehouseFlowId(lWarehouseFlowId); whGoodsRecord.setBaseGoodsTemplateId(tempGoodsId); whGoodsRecord.setGoodsTemplateName(goodsName); whGoodsRecord.setBaseGoodsModelsId(baseGoodsModelsId); whGoodsRecord.setBaseGoodsModelsName(modelName); whGoodsRecord.setDealTime(dealTime); //本次调整类型 1=调增;2=调减 whGoodsRecord.setThisType(2); whGoodsRecord.setThisCount(counts); //通过LockManage获得锁 Object warehouseModelLockObj = LockManage.acquireLock(outWarehouseId, baseGoodsModelsId); synchronized (warehouseModelLockObj) { // 获得锁后查询该型号的期初数量 int goodsModelNum = lWhGoodsService.queryGoodsModelNum(outWarehouseId, baseGoodsModelsId, queryModelStatus, buyType); if (goodsModelNum < counts) { log.error("出库失败!型号{} 的数量不足,需要调拨{}个,仓库中现存{}个", baseGoodsModelsId, counts, goodsModelNum); // 手动回滚 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); throw new RuntimeException("出库失败!型号数量不足"); } whGoodsRecord.setInitialCount(goodsModelNum); whGoodsRecord.setEndCount(goodsModelNum - counts); //出库时候,按 先入库的先出库,同时入库的,按价格高的先出库 List outGoodsId = lWhGoodsService.queryOutGoodsId(outWarehouseId, baseGoodsModelsId, queryModelStatus, buyType, goodsModelNum); outGoodsId.forEach(whGoodsId -> { }); } }); LWarehouseFlow warehouseFlow = new LWarehouseFlow(); warehouseFlow.setId(lWarehouseFlowId); warehouseFlow.setWarehouseId(outWarehouseId); warehouseFlow.setWarehouseName(warehouseName); warehouseFlow.setThisType(2); warehouseFlow.setBusinessType(WhBusinessEnum.DIAOBO.getValue() + 0); warehouseFlow.setBusinessFormId(lWarehouseFlowBusinessId); warehouseFlow.setOperatorId(userId); warehouseFlow.setOperatorName(nickName); warehouseFlow.setDealTime(dealTime); // 插入流水总表 int flowInsertFlag = lWarehouseFlowService.insert(warehouseFlow); if (flowInsertFlag == 0) { return 0l; } return 1l; } }