package com.consum.base.service.impl; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.interceptor.TransactionAspectSupport; import com.consum.base.core.CodeGeneratorEnum; import com.consum.base.core.CodeGeneratorService; import com.consum.base.core.WhBusinessEnum; import com.consum.base.core.service.LWhWarningCoreServiceImpl; import com.consum.base.core.type.InAndOutPutType; import com.consum.base.core.type.OutPutStatesType; import com.consum.base.core.utils.IdUtil; import com.consum.base.core.utils.LockManage; import com.consum.base.service.BaseGoodsTemplateService; import com.consum.base.service.LWarehouseFlowService; import com.consum.base.service.LWhFormOutputService; import com.consum.base.service.LWhGoodsRecordService; import com.consum.base.service.LWhGoodsService; import com.consum.base.service.LWhProcureModelService; import com.consum.model.po.LWarehouseFlow; import com.consum.model.po.LWhFormOutput; import com.consum.model.po.LWhFormTransfer; import com.consum.model.po.LWhGoodsRecord; import com.consum.model.po.LWhProcureModel; import com.iplatform.model.po.S_user_core; import com.walker.infrastructure.utils.CollectionUtils; import com.walker.infrastructure.utils.NumberGenerator; import cn.hutool.core.convert.Convert; import lombok.extern.slf4j.Slf4j; /** * @ClassName WhFormOutputCoreService * @Date 2023/10/26 * @Description * @Version 1.0 **/ @Slf4j @Service @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED) public class LWhFormOutputCoreService { private BaseGoodsTemplateService baseGoodsTemplateService; private LWhGoodsService lWhGoodsService; private CodeGeneratorService codeGeneratorService; private LWhProcureModelService lWhProcureModelService; private LWhFormOutputService lWhFormOutputService; private LWhWarningCoreServiceImpl lWhWarningCoreService; private LWarehouseFlowService lWarehouseFlowService; private LWhGoodsRecordDetailsService lWhGoodsRecordDetailsService; private LWhGoodsRecordService lWhGoodsRecordServiceImpl; @Autowired public LWhFormOutputCoreService(BaseGoodsTemplateService baseGoodsTemplateService, LWhGoodsService lWhGoodsService, CodeGeneratorService codeGeneratorService, LWhProcureModelService lWhProcureModelService, LWhFormOutputService lWhFormOutputService, LWarehouseFlowService lWarehouseFlowService, LWhGoodsRecordDetailsService lWhGoodsRecordDetailsService, LWhGoodsRecordService lWhGoodsRecordServiceImpl, LWhWarningCoreServiceImpl lWhWarningCoreService) { this.baseGoodsTemplateService = baseGoodsTemplateService; this.lWhGoodsService = lWhGoodsService; this.codeGeneratorService = codeGeneratorService; this.lWhProcureModelService = lWhProcureModelService; this.lWhFormOutputService = lWhFormOutputService; this.lWarehouseFlowService = lWarehouseFlowService; this.lWhGoodsRecordDetailsService = lWhGoodsRecordDetailsService; this.lWhGoodsRecordServiceImpl = lWhGoodsRecordServiceImpl; this.lWhWarningCoreService = lWhWarningCoreService; } /** * 根据 调拨单 生成 出库单 * * @param whFormTransferId 调拨单id * @return 出库单Id */ @Transactional(rollbackFor = Exception.class) public Long createOutFormByTransId(Long whFormTransferId, WhBusinessEnum businessEnum, S_user_core currentUser, Long dealTime) { if (whFormTransferId == null) { return null; } LWhFormTransfer lWhFormTransfer = new LWhFormTransfer(whFormTransferId); lWhFormTransfer = lWhFormOutputService.get(lWhFormTransfer); if (lWhFormTransfer == null || lWhFormTransfer.getStates() != 0) { log.error("调拨失败!请检查调拨单状态"); return null; } // 查询该调拨单是否已经生成了出库单 Long outWarehouseFormId = lWhFormOutputService.queyrIdByTransferId(whFormTransferId); if (outWarehouseFormId != null) { return outWarehouseFormId; } // 出库单ID outWarehouseFormId = NumberGenerator.getLongSequenceNumberNano(); // 申请调拨的物品 List goodsModelNumList = lWhProcureModelService.getModelByForm(businessEnum, whFormTransferId); if (CollectionUtils.isEmpty(goodsModelNumList)) { log.error("没有要入库的物品"); throw new RuntimeException("没有要入库的物品"); } Long outWarehouseId = lWhFormTransfer.getOutWarehouseId(); String outWarehouseName = lWhFormTransfer.getOutWarehouseName(); // 调拨单物品 已经按型号分好了 for (LWhProcureModel itemModelInfo : goodsModelNumList) { // 复用对象 itemModelInfo.setId(IdUtil.generateId()); itemModelInfo.setFromProcureGoodsId(null); itemModelInfo.setBusinessType(3); itemModelInfo.setBusinessId(outWarehouseFormId); itemModelInfo.setPrice(null); itemModelInfo.setSupplier(null); } lWhProcureModelService.insertBatch(goodsModelNumList); // //创建出库单 LWhFormOutput whFormOutput = new LWhFormOutput(); whFormOutput.setId(outWarehouseFormId); // 此时并没有出库 whFormOutput.setWarehouseFlowId(null); whFormOutput .setBusinessFormCode(codeGeneratorService.createBusinessFormCode(CodeGeneratorEnum.OutPut_Warehouse)); // 进出库流水总表 入库单ID whFormOutput.setInWarehouseFlowId(null); // 调拨单ID(调拨时需要) whFormOutput.setTransBusinessId(whFormTransferId); whFormOutput.setOutputCode(InAndOutPutType.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()); whFormOutput.setDealTime(dealTime); whFormOutput.setStates(OutPutStatesType.OUT_PENDING.getValue()); int insert = lWhFormOutputService.insert(whFormOutput); if (insert == 0) { TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return null; } return outWarehouseFormId; } /** * 根据 出库单 出库 * * @param outWarehouseFormId 出库单Id * @return 流水记录总表ID */ @Transactional(rollbackFor = Exception.class) public Long outFormByTransId(Long outWarehouseFormId, WhBusinessEnum businessType, S_user_core currentUser, Long dealTime, Long whFormTransferId) { 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 Integer outWarehouseType = lWhFormOutput.getOutWarehouseType(); Long outWarehouseId = lWhFormOutput.getWarehouseId(); String warehouseName = lWhFormOutput.getWarehouseName(); Integer inWarehouseType = lWhFormOutput.getInWarehouseType(); Long inWarehouseId = lWhFormOutput.getInWarehouseId(); String inWarehouseName = lWhFormOutput.getInWarehouseName(); Long userId = currentUser.getId(); String nickName = currentUser.getNick_name(); // 流水记录总表ID long lWarehouseFlowId = NumberGenerator.getLongSequenceNumberNano(); long lWarehouseFlowBusinessId = outWarehouseFormId; Integer queryModelStatus = 1; Integer buyType = null; Integer modGoodsTransferStatus = null; Integer businessTypeValue = businessType.getValue(); if (businessTypeValue == InAndOutPutType.Transfer_Output.getValue()) { // 调拨出库 queryModelStatus = 0; buyType = 1; lWarehouseFlowBusinessId = lWhFormOutput.getTransBusinessId(); modGoodsTransferStatus = 0; } else if (businessTypeValue == InAndOutPutType.Dept_Lending_Out.getValue()) { // 部门仓库 分发出库 lWarehouseFlowBusinessId = lWhFormOutput.getTransBusinessId(); } else if (businessTypeValue == InAndOutPutType.Fragmentary_Output.getValue() || businessTypeValue == InAndOutPutType.Inventory_Output.getValue()) { // 零星出库 或 盘点出库 queryModelStatus = 1; modGoodsTransferStatus = 4; } ArrayList allChangModelList = new ArrayList<>(); for (LWhProcureModel itemModelInfo : goodsModelNumList) { // 需要调拨的物品的某个型号 Long baseGoodsModelsId = itemModelInfo.getBaseGoodsModelsId(); // TODO 为空时不加入更新列表 if (baseGoodsModelsId != null) { allChangModelList.add(baseGoodsModelsId); } // 需要调拨的物品某个型号的数量 Integer counts = itemModelInfo.getCounts(); // 查询型号信息 Map tempGoodsInfo = baseGoodsTemplateService.queryGoodsInfoByModelId(baseGoodsModelsId); Long tempGoodsId = (Long)tempGoodsInfo.get("goodsid"); String goodsName = (String)tempGoodsInfo.get("goodsname"); String modelName = (String)tempGoodsInfo.get("modelname"); // 插入 各规格物品的进出库记录 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(outWarehouseType, outWarehouseId, baseGoodsModelsId); List outGoodsId = null; synchronized (warehouseModelLockObj) { // 获得锁后查询该型号的期初数量 List warehouseIds = new ArrayList<>(Arrays.asList(outWarehouseId)); int goodsModelNum = lWhGoodsService.queryGoodsModelNum(outWarehouseType, warehouseIds, baseGoodsModelsId, queryModelStatus, buyType); if (goodsModelNum < counts) { log.error("出库失败!型号{} 的数量不足,需要调拨{}个,仓库中现存{}个", baseGoodsModelsId, counts, goodsModelNum); // 手动回滚 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); throw new RuntimeException("出库失败!型号数量不足"); } whGoodsRecord.setInitialCount(goodsModelNum); whGoodsRecord.setEndCount(goodsModelNum - counts); // 出库时候,按 先入库的先出库,同时入库的,按价格高的先出库 outGoodsId = lWhGoodsService.queryOutGoodsId(outWarehouseType, outWarehouseId, baseGoodsModelsId, queryModelStatus, buyType, counts); lWhGoodsService.modGoodsTransfering(outGoodsId, inWarehouseType, inWarehouseId, inWarehouseName, modGoodsTransferStatus); // 批量插入 进出库流水明细[L_WH_GOODS_RECORD_DETAILS] lWhGoodsRecordDetailsService.sameGoodsInsertMore(outGoodsId, whGoodsRecordId, (short)0); } long totalAmount = lWhGoodsService.queryGoodsPriceById(outGoodsId); LWhProcureModel lWhProcureModel = new LWhProcureModel(itemModelInfo.getId()); whGoodsRecord.setTotalPrice(totalAmount); lWhGoodsRecordServiceImpl.insert(whGoodsRecord); lWhProcureModel.setTotalAmount(totalAmount); lWhProcureModelService.update(lWhProcureModel); } LWarehouseFlow warehouseFlow = new LWarehouseFlow(); warehouseFlow.setId(lWarehouseFlowId); warehouseFlow.setWarehouseId(outWarehouseId); warehouseFlow.setWarehouseName(warehouseName); warehouseFlow.setThisType(2); warehouseFlow.setBusinessType(businessType.getValue()); warehouseFlow.setBusinessFormId(whFormTransferId == null ? lWarehouseFlowBusinessId : whFormTransferId); warehouseFlow.setOperatorId(userId); warehouseFlow.setOperatorName(nickName); warehouseFlow.setDealTime(dealTime); // 插入流水总表 int flowInsertFlag = lWarehouseFlowService.insert(warehouseFlow); if (flowInsertFlag == 0) { return null; } // 向出库单 插入 进出库流水总表ID lWhFormOutput = new LWhFormOutput(outWarehouseFormId); lWhFormOutput.setStates(OutPutStatesType.OUT_SUCCESS.getValue()); lWhFormOutput.setWarehouseFlowId(lWarehouseFlowId); lWhFormOutputService.update(lWhFormOutput); // 当库存变动时调用该方法 if (outWarehouseType == 0) { lWhWarningCoreService.updateKuCun(Convert.toShort(outWarehouseType, (short)0), outWarehouseId, allChangModelList, null, dealTime); } return lWarehouseFlowId; } }