Files
scrq-hd/.svn/pristine/86/864a1da670d7e1b10adf3cc3e20f9fecb826a0f3.svn-base
2025-07-03 10:34:04 +08:00

964 lines
39 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.cmeim.biz.service;
import com.alibaba.fastjson.JSONObject;
import com.cmeim.basic.api.RemoteMaterialService;
import com.cmeim.basic.api.RemoteSyDictService;
import com.cmeim.basic.api.dto.MaterialDto;
import com.cmeim.basic.api.dto.SyDictDto;
import com.cmeim.biz.dto.InputTypeCountDto;
import com.cmeim.biz.dto.InputTypeParDto;
import com.cmeim.biz.po.MmInputBill;
import com.cmeim.biz.po.MmInputBillDetail;
import com.cmeim.biz.po.MmInputBillItem;
import com.cmeim.biz.po.MmMaterialBar;
import com.cmeim.biz.po.MmOtherInputBillDetail;
import com.cmeim.biz.po.MmPickBill;
import com.cmeim.biz.po.MmPickBillDetail;
import com.cmeim.biz.po.MmPickBillItem;
import com.cmeim.biz.po.MmReturnBillDetail;
import com.cmeim.biz.po.MmSporadicPickBill;
import com.cmeim.biz.po.MmSporadicPickBillDetail;
import com.cmeim.biz.repository.MmInputBillDetailRepository;
import com.cmeim.biz.repository.MmInputBillItemRepository;
import com.cmeim.biz.repository.MmInputBillRepository;
import com.cmeim.biz.repository.MmMaterialBarRepository;
import com.cmeim.biz.repository.MmOtherInputBillDetailRepository;
import com.cmeim.biz.repository.MmReturnBillDetailRepository;
import com.cmeim.biz.vo.InputBillDetailVo;
import com.cmeim.biz.vo.InputStockInRedVo;
import com.cmeim.biz.vo.MaterialBarVo;
import com.cmeim.biz.vo.PickBillDetailVo;
import com.cmeim.biz.vo.WCSLampArray;
import com.cmeim.biz.vo.WCSStoreLampVo;
import com.cmeim.biz.vo.app.AnalysisBarVo;
import com.cmeim.biz.vo.app.HIKBarvo;
import com.cmeim.biz.vo.app.SporadicRedPickSaveVo;
import com.cmeim.common.core.domain.R;
import com.cmeim.common.core.exception.ServiceException;
import com.cmeim.common.core.utils.BeanUtil;
import com.cmeim.common.core.utils.DateUtil;
import com.cmeim.common.core.utils.DateUtils;
import com.cmeim.common.core.utils.SecurityUtils;
import com.cmeim.common.core.web.domain.RespondEnum;
import com.cmeim.integrate.dto.WCSStoreLampStatusDto;
import com.cmeim.kafka.api.Topic;
import com.cmeim.stock.dto.BaLocationDto;
import com.cmeim.stock.dto.MaterialBarDto;
import com.cmeim.stock.dto.MmStockDto;
import com.cmeim.stock.po.BaLocation;
import com.cmeim.stock.po.BaLocationRecommend;
import com.cmeim.stock.po.BaWarehouse;
import com.cmeim.stock.po.MmAllocationBill;
import com.cmeim.stock.po.MmAllocationDetail;
import com.cmeim.stock.po.MmAllocationItem;
import com.cmeim.stock.po.MmStock;
import com.cmeim.stock.repository.BaWareHouseRepository;
import com.cmeim.stock.repository.BalocationRecommendRepository;
import com.cmeim.stock.repository.BalocationRepository;
import com.cmeim.stock.repository.MmStockRepository;
import com.cmeim.stock.service.api.MaterialBarService;
import com.cmeim.stock.service.api.StockService;
import com.cmeim.stock.vo.stock.CreateBar;
import com.cmeim.stock.vo.stock.StockInVo;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
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;
@Slf4j
@Service
public class InputAppService {
@Autowired
private MmMaterialBarRepository materialBarRepository;
@Autowired
private RemoteMaterialService remoteMaterialService;
@Autowired
private BalocationRepository balocationRepository;
@Autowired
private RemoteSyDictService remoteSyDictService;
@Autowired
private KafkaTemplate kafkaTemplate;
@Autowired
private BaWareHouseRepository baWareHouseRepository;
@Autowired
private MmInputBillDetailRepository inputBillDetailRepository;
@Autowired
private MmOtherInputBillDetailRepository otherInputBillDetailRepository;
@Autowired
private MmReturnBillDetailRepository returnBillDetailRepository;
@Autowired
private InputRemoteService remoteService;
@Autowired
private MmInputBillRepository mmInputBillRepository;
@Autowired
private BalocationRecommendRepository balocationRecommendRepository;
@Autowired
private MaterialBarService materialBarService;
@Autowired
private StockService stockService;
@Autowired
private OutputRemoteService outputRemoteService;
@Autowired
private MmInputBillItemRepository mmInputBillItemRepository;
@Autowired
private MmStockRepository stockRepository;
@Autowired
private InputRemoteService inputRemoteService;
private static Map<String, Integer> numberColorMap = new HashMap<>();
private static Map<String, WCSStoreLampVo> numberLampMap = new HashMap<>();
private static Integer colorIndex = 0;
private static Map<String, Map<String, BigDecimal>> staticMaterialMap = new HashMap<>();
private static Map<String, Map<String, Map<String, BigDecimal>>> staticMaterialAndLocationMap = new HashMap<>();
/**
* 自动转换虚拟条码到库存条码
*
* @param materialBar 物料条码
* @return 返回值
*/
@Transactional
public MaterialBarVo autoCreateBar(String materialBar) {
if (materialBar.length() < 10) {
throw new ServiceException(RespondEnum.SYSTEM_ERROR, String.format("生产工单状态【%s】", materialBar));
}
String[] barDtl = materialBar.split("@");
MaterialBarVo returnMaterialBarVo = new MaterialBarVo();
if (barDtl.length > 1) {
//如果找到百分号,取第一个百分号前字符串作为查询条件
MaterialDto getMaterialDto = new MaterialDto();
getMaterialDto.setMaterialCode(barDtl[0]);
List<MaterialDto> materialDtoList = remoteService.queryFindBack(getMaterialDto);
if (materialDtoList.size() > 0) {
MaterialDto materialDto = materialDtoList.get(0);
MmMaterialBar mmMaterialBar = new MmMaterialBar();
mmMaterialBar.setMaterialBar(materialBar);
mmMaterialBar.setMaterialId(materialDto.getId());
mmMaterialBar.setMaterialCode(materialDto.getMaterialCode());
mmMaterialBar.setMaterialName(materialDto.getMaterialName());
mmMaterialBar.setMaterialQty(BigDecimal.ZERO);
mmMaterialBar.setMaterialSpec(materialDto.getMaterialSpec());
mmMaterialBar.setCreatedBy(SecurityUtils.getUsername());
mmMaterialBar.setCreatedDt(DateUtil.getCurrentDate());
materialBarRepository.save(mmMaterialBar);
returnMaterialBarVo = BeanUtil.copyProperties(mmMaterialBar, MaterialBarVo.class);
return returnMaterialBarVo;
}
} else {
String materialCode = materialBar.substring(0, 9);
MaterialDto getMaterialDto = new MaterialDto();
getMaterialDto.setMaterialCode(materialCode);
List<MaterialDto> materialDtoList = remoteService.queryFindBack(getMaterialDto);
for (int i = 0; i < 10; i++) {
if (materialDtoList.size() == 1) {
MaterialDto materialDto = materialDtoList.get(0);
MmMaterialBar mmMaterialBar = new MmMaterialBar();
mmMaterialBar.setMaterialBar(materialBar);
mmMaterialBar.setMaterialId(materialDto.getId());
mmMaterialBar.setMaterialCode(materialDto.getMaterialCode());
mmMaterialBar.setMaterialName(materialDto.getMaterialName());
mmMaterialBar.setMaterialQty(BigDecimal.ZERO);
mmMaterialBar.setMaterialSpec(materialDto.getMaterialSpec());
mmMaterialBar.setCreatedBy(SecurityUtils.getUsername());
mmMaterialBar.setCreatedDt(DateUtil.getCurrentDate());
materialBarRepository.save(mmMaterialBar);
returnMaterialBarVo = BeanUtil.copyProperties(mmMaterialBar, MaterialBarVo.class);
return returnMaterialBarVo;
} else {
materialCode = materialBar.substring(0, 10 + i);
getMaterialDto = new MaterialDto();
getMaterialDto.setMaterialCode(materialCode);
materialDtoList = remoteService.queryFindBack(getMaterialDto);
}
}
}
return returnMaterialBarVo;
}
/**
* 条码判断
*
* @param code 物料条码
* @return 结果值
*/
public AnalysisBarVo analysisBar(String code) {
AnalysisBarVo vo = new AnalysisBarVo();
MmMaterialBar materialBar = materialBarRepository.findByMaterialBar(code);
if (materialBar != null) {
MaterialBarVo barVo = BeanUtil.copyProperties(materialBar, MaterialBarVo.class);
R<MaterialDto> materialDtoR = remoteMaterialService.findByMaterialCode(materialBar.getMaterialCode());
if (materialDtoR.getCode() == 200 && materialDtoR.getData() != null) {
barVo.setMaterialSpec(materialDtoR.getData().getMaterialSpec());
}
String inputBillNumber = barVo.getInputBillNumber();
Long arriveBillDetailId = barVo.getArriveBillDetailId();
String batchNo = barVo.getBatchNo();
if (StringUtils.isNotEmpty(inputBillNumber) && null != arriveBillDetailId && StringUtils.isNotEmpty(batchNo)) {
MmInputBillDetail inputBillDetail =
inputBillDetailRepository.findByInputBillNumberAndArriveBillDetailIdAndBatchNo(inputBillNumber,
arriveBillDetailId, batchNo);
if (null != inputBillDetail) {
barVo.setInputPlanQty(inputBillDetail.getPlanQty());
barVo.setInputRealQty(inputBillDetail.getRealQty());
}
}
vo.setType(1);
vo.setData(barVo);
return vo;
}
BaLocation byLocationCode = balocationRepository.findByLocationCode(code);
if (byLocationCode != null) {
BaLocationDto data = BeanUtil.copyProperties(byLocationCode, BaLocationDto.class);
vo.setType(2);
vo.setData(data);
return vo;
}
// 54位的海康条码和44位的海康条码
if (code.length() == 44 || code.length() == 54) {
String materialCode = code.substring(0, 9);
String bacthNo = code.length() == 44 ? DateUtils.dateTime() : code.substring(9, 19);
bacthNo = bacthNo.replaceAll("^(0+)", "");
BigDecimal materialQty = new BigDecimal(code.length() == 44 ? code.substring(35, 44) : code.substring(45,
54));
HIKBarvo hikBarvo = new HIKBarvo(materialCode, bacthNo, materialQty);
R<MaterialDto> materialDtoR = remoteMaterialService.findByMaterialCode(materialCode);
if (materialDtoR.getCode() == 200) {
MaterialDto materialDto = materialDtoR.getData();
if (materialDto != null) {
hikBarvo.setMaterialId(materialDto.getId());
hikBarvo.setMaterialName(materialDto.getMaterialName());
hikBarvo.setMaterialSpec(materialDto.getMaterialSpec());
}
}
vo.setType(-1);
vo.setData(hikBarvo);
return vo;
}
return null;
}
/**
* 业务字典查询
*
* @param groupCode 业务字典组
* @param key 业务字典key值
* @return 返回值
*/
public String findTextByGroupCodeAndKey(String groupCode, Integer key) {
if (null == key) {
return "";
}
SyDictDto dto = new SyDictDto();
dto.setGroupCode(groupCode);
dto.setGroupKey(key);
R<List<SyDictDto>> query = remoteSyDictService.query(dto);
if (query.getCode() != 200 || query.getData() == null || query.getData().size() == 0) {
return "";
} else {
List<SyDictDto> dictDtoList = query.getData();
if (dictDtoList.size() == 1) {
return query.getData().get(0).getGroupText();
} else {
for (SyDictDto dictDto : dictDtoList) {
if (key.equals(dictDto.getGroupKey())) {
return dictDto.getGroupText();
}
}
return "";
}
}
}
/**
* 业务字典查询
*
* @param groupCode 业务字典组
* @return 返回值
*/
public List<SyDictDto> findTextByGroupCode(String groupCode) {
SyDictDto dto = new SyDictDto();
dto.setGroupCode(groupCode);
R<List<SyDictDto>> query = remoteSyDictService.query(dto);
List<SyDictDto> dictDtoList = new ArrayList<>();
if (query.getCode() != 200 || query.getData() == null || query.getData().size() == 0) {
return dictDtoList;
} else {
dictDtoList = query.getData();
return dictDtoList;
}
}
/**
* 判断库位是否为空
*
* @param warehouseCode 库位
* @param materialBarVo 物料数据
* @return 操作结果
*/
public MaterialBarVo isEmpty(String warehouseCode, MaterialBarVo materialBarVo) {
if (StringUtils.isNotEmpty(warehouseCode)) {
BaWarehouse baWarehouse = baWareHouseRepository.findByWarehouseCode(warehouseCode);
materialBarVo.setWarehouseCode(baWarehouse.getWarehouseCode() + " " + baWarehouse.getWarehouseName());
}
return materialBarVo;
}
/**
* 判断
*
* @param mmInputBillType 判断值
* @return 结果值
*/
public String judge1(Integer mmInputBillType) {
String name = null;
if (mmInputBillType == null) {
return null;
} else {
switch (mmInputBillType) {
case 5:
name = "不良品入库";
break;
case 10:
name = "良品入库";
break;
case 15:
name = "入库撤回";
break;
default:
name = null;
break;
}
return name;
}
}
/**
* 判断
*
* @param mmInputBillType 判断值
* @return 结果值
*/
public String judge2(Integer mmInputBillType) {
String name = null;
if (mmInputBillType == null) {
return null;
} else {
switch (mmInputBillType) {
case 0:
name = "CP";
break;
case 1:
name = "SP";
break;
default:
name = null;
}
return name;
}
}
/**
* 判断
*
* @param mmInputBillStatus 判断值
* @return 结果值
*/
public String judge3(Integer mmInputBillStatus) {
String name = null;
if (mmInputBillStatus == null) {
return null;
} else {
switch (mmInputBillStatus) {
case 1:
name = "待入库";
break;
case 2:
name = "部分入库";
break;
case 3:
name = "已入库";
break;
case 21:
name = "待撤回";
break;
case 22:
name = "部分撤回";
break;
case 23:
name = "已撤回";
break;
default:
name = null;
}
return name;
}
}
/**
* 判断
*
* @param mmInputBillStatusERP 判断值
* @return 结果值
*/
public String judge4(Integer mmInputBillStatusERP) {
String name = null;
if (mmInputBillStatusERP == null) {
return null;
} else {
switch (mmInputBillStatusERP) {
case 1:
name = "待同步";
break;
case 2:
name = "同步成功";
break;
case 3:
name = "同步失败";
break;
case 4:
name = "已同步上传";
break;
default:
name = null;
}
return name;
}
}
/**
* 判断
*
* @param mmArriveBillMaterialAttr 判断值
* @return 结果值
*/
public String judge5(Integer mmArriveBillMaterialAttr) {
String name = null;
if (mmArriveBillMaterialAttr == null) {
return null;
} else {
switch (mmArriveBillMaterialAttr) {
case 1031:
name = "其他";
break;
case 1110:
name = "贴片";
break;
case 1300:
name = "插件";
break;
case 1301:
name = "组装";
break;
case 1610:
name = "不良品";
break;
default:
name = null;
}
return name;
}
}
/**
* 判断
*
* @param arriveBillIsInspect 判断值
* @return 结果值
*/
public String judge6(Integer arriveBillIsInspect) {
String name = null;
if (arriveBillIsInspect == null) {
return null;
} else {
switch (arriveBillIsInspect) {
case 0:
name = "CP";
break;
case 1:
name = "SP";
break;
default:
name = null;
}
return name;
}
}
/**
* 亮灯
*
* @param lamp 亮灯参数
*/
public void lightUp(WCSLampArray lamp) {
WCSStoreLampVo lampDto = new WCSStoreLampVo();
List<WCSLampArray> arrayList = new ArrayList<>();
lamp.setLightUpModel("常亮");
arrayList.add(lamp);
lampDto.setControlList(arrayList);
kafkaTemplate.send(Topic.Output.CONTROL_ELECLABEL, JSONObject.toJSONString(lampDto));
log.info("亮灯,topic:{}, data:{}", Topic.Input.INPUT_LAMP_OP, JSONObject.toJSONString(lampDto));
}
/**
* 熄灯
*
* @param lamp 熄灯参数
*/
public void lightOff(WCSLampArray lamp) {
WCSStoreLampVo lampDto = new WCSStoreLampVo();
List<WCSLampArray> arrayList = new ArrayList<>();
lamp.setLightUpModel("关闭");
arrayList.add(lamp);
lampDto.setControlList(arrayList);
kafkaTemplate.send(Topic.Output.CONTROL_ELECLABEL, JSONObject.toJSONString(lampDto));
log.info("熄灯,topic:{}, data:{}", Topic.Input.INPUT_LAMP_OP, JSONObject.toJSONString(lampDto));
}
/**
* 亮灯复位
*
* @param locationCode 库位
*/
public void lightReset(String locationCode) {
WCSStoreLampStatusDto dto = new WCSStoreLampStatusDto();
dto.setOpUser(SecurityUtils.getUsername());
dto.setFuncation(5);
dto.setShelfCode(locationCode);
dto.setLightColour(1);
kafkaTemplate.send(Topic.Input.INPUT_LAMP_RESET, JSONObject.toJSONString(dto));
log.info("复位,topic:{}, data:{}", Topic.Input.INPUT_LAMP_OP, JSONObject.toJSONString(dto));
}
/**
* 入库查询
*
* @param par 入库时间段
* @return 查询结果
*/
public InputTypeCountDto inputTypeCount(InputTypeParDto par) {
InputTypeCountDto dto = new InputTypeCountDto();
//查询入库单总数
List<MmInputBillDetail> inspectBillDetailList =
inputBillDetailRepository.findByCreatedDtGreaterThanEqualAndCreatedDtLessThanEqual(par.getStartTime(),
par.getEndTime());
dto.setInputCount((long) inspectBillDetailList.size());
//查询其他入库单总数
List<MmOtherInputBillDetail> otherInputBillDetailList =
otherInputBillDetailRepository.findByCreatedDtGreaterThanEqualAndCreatedDtLessThanEqual(par.getStartTime(), par.getEndTime());
dto.setOtherInputCount((long) otherInputBillDetailList.size());
//查询退库库单总数
List<MmReturnBillDetail> returnBillDetailList =
returnBillDetailRepository.findByCreatedDtGreaterThanEqualAndCreatedDtLessThanEqual(par.getStartTime(), par.getEndTime());
dto.setReturnCount((long) returnBillDetailList.size());
return dto;
}
@Transactional
public MmMaterialBar inputStockInRed(@RequestBody InputStockInRedVo vo) {
MmInputBill mmInputBill = mmInputBillRepository.findByInputBillNumber(vo.getInputNumber());
//判断入库单存不存在
if (mmInputBill == null) {
throw new ServiceException(RespondEnum.FAILURE, "查询相关入库单失败!");
}
//判断条码是否入库并修改条码库位
MmMaterialBar mmMaterialBar = materialBarRepository.findByMaterialBar(vo.getMaterialBar());
if (mmMaterialBar == null) {
throw new ServiceException(RespondEnum.FAILURE, "条码不存在!");
}
MaterialDto materialDto = BeanUtil.copyProperties(mmMaterialBar, MaterialDto.class);
// 更新库存信息
if (StringUtils.isEmpty(mmMaterialBar.getLocationCode())) {
throw new ServiceException(RespondEnum.FAILURE, "条码表库位暂时,该条码是否已入库!");
}
//判断是否重复红字入库
MmInputBillItem mm = mmInputBillItemRepository.findByInputBillNumberAndMaterialBar(vo.getInputNumber(), vo.getMaterialBar());
if (mm != null) {
throw new ServiceException(RespondEnum.FAILURE, String.format(
"通过入库单【%s】条码【%s】查询记录表里面已经有红字入库数据无法重复使用", vo.getInputNumber(), vo.getMaterialBar()));
}
BaLocation baLocation = balocationRepository.findByLocationCode(mmMaterialBar.getLocationCode());
StockInVo stockInVo = new StockInVo();
stockInVo.setMaterialBar(vo.getMaterialBar());
stockInVo.setBatchNo(mmMaterialBar.getBatchNo());
stockInVo.setQty(vo.getQty());
stockInVo.setBillId(mmInputBill.getId());
stockInVo.setBillNumber(mmInputBill.getInputBillNumber());
stockInVo.setMaterialDto(materialDto);
stockInVo.setDictBizType(48);
stockInVo.setTargetWarehouseType(10);
BaWarehouse byWarehouseCode1 = baWareHouseRepository.findByWarehouseCode(mmInputBill.getWarehouseCode());
stockInVo.setTargetBaWarehouse(byWarehouseCode1);
stockInVo.setInspectBillNumber(mmMaterialBar.getInspectBillNumber());
stockInVo.setFromBaWarehouse(byWarehouseCode1);
stockInVo.setTargetBaLocation(baLocation);
stockInVo.setFromBaLocation(baLocation);
stockInVo.setDictBilltype(55);//单据类型:红字入库单
log.info("红字入库StockInVo"+stockInVo);
MmMaterialBar mmMaterialBar1 = stockService.stockOut(stockInVo, false, false);
//修改单据明细
mmInputBill.getItems().forEach(detail -> {
if (detail.getMaterialCode().equals(materialDto.getMaterialCode())) {
if (detail.getRealQty().compareTo(BigDecimal.ZERO) == 0) {
detail.setRealQty(detail.getRealQty().negate().add(vo.getQty().negate()));
} else {
detail.setRealQty(detail.getRealQty().add(vo.getQty().negate()));
}
log.info("红字入库单据:"+vo.getInputNumber()+"实发数量:"+detail.getRealQty());
// 修改领料明细数量
if (detail.getPlanQty().abs().compareTo(detail.getRealQty().abs()) <= 0) {
detail.setDictStatus(23);
} else {
detail.setDictStatus(22);
}
detail.setUpdatedBy(SecurityUtils.getUsername());
detail.setUpdatedDt(DateUtil.getCurrentDate());
log.info("红字入库回写明细数据:"+detail);
//添加红字入库记录
MmInputBillItem mmInputBillItem= BeanUtil.copyProperties(detail,MmInputBillItem.class);
mmInputBillItem.setId(null);
mmInputBillItem.setMaterialBar(vo.getMaterialBar());
if (mmMaterialBar1 != null && StringUtils.isNotBlank(mmMaterialBar1.getMaterialBar())) {
mmInputBillItem.setMaterialBar(mmMaterialBar1.getMaterialBar());
}
mmInputBillItem.setQty(vo.getQty().abs());
mmInputBillItem.setCreatedBy(SecurityUtils.getUsername());
mmInputBillItem.setCreatedDt(DateUtil.getCurrentDate());
mmInputBillItemRepository.save(mmInputBillItem);
}
});
log.info("红字出库保存接口---GCB-------》7");
List<MmInputBillDetail> filter =
mmInputBill.getItems().stream().filter(detail -> detail.getDictStatus() == 23).collect(Collectors.toList());
if (filter.size() == mmInputBill.getItems().size()) {
mmInputBill.setDictStatus(23);
} else {
mmInputBill.setDictStatus(22);
}
mmInputBill.setUpdatedBy(SecurityUtils.getUsername());
mmInputBill.setUpdatedDt(DateUtil.getCurrentDate());
mmInputBillRepository.save(mmInputBill);
return mmMaterialBar1;
}
/**
* pickLightUp
*/
public String pickLightUp(String inputBillNumber) {
MmInputBill pickBill = mmInputBillRepository.findByInputBillNumber(inputBillNumber);
// key=物料, value=数量
Map<String, BigDecimal> materialMap = new HashMap<>();
// key=物料, value=map<库位、数量>
Map<String, Map<String, BigDecimal>> materialAndLocationMap = new HashMap<>();
for (MmInputBillDetail detail : pickBill.getItems()) {
List<MmStock> mmStockList = stockRepository.findAllByMaterialCode(detail.getMaterialCode());
if (detail.getDictStatus() == 20 || mmStockList.size() == 0) {
continue;
}
List<MmStock> recommendStockList = new ArrayList<>();
BigDecimal planQty = detail.getPlanQty();
for (MmStock stock : mmStockList) {
BigDecimal qty = stock.getQty();
planQty = planQty.subtract(qty);
recommendStockList.add(stock);
// 添加库位和数量到第二个map里面
Map<String, BigDecimal> map = materialAndLocationMap.get(detail.getMaterialCode());
if (map == null) {
map = new HashMap<>();
materialAndLocationMap.put(detail.getMaterialCode(), map);
}
BigDecimal locationQty = map.get(stock.getLocationCode());
if (locationQty == null) {
locationQty = BigDecimal.ZERO;
}
locationQty = locationQty.add(stock.getQty());
map.put(stock.getLocationCode(), locationQty);
if (planQty.compareTo(BigDecimal.ZERO) < 1) {
break;
}
}
materialMap.put(detail.getMaterialCode(), detail.getPlanQty());
}
Set<String> locationCodeSet = new HashSet<String>();
Collection<Map<String, BigDecimal>> values = materialAndLocationMap.values();
values.stream().forEach(map -> {
locationCodeSet.addAll(map.keySet());
});
// 获取颜色
Integer color = getColor(inputBillNumber);
WCSStoreLampVo lampDto = new WCSStoreLampVo();
List<WCSLampArray> arrayList = new ArrayList<>();
locationCodeSet.forEach(locationCode -> {
WCSLampArray arr = new WCSLampArray();
arr.setLightColour("红色");
arr.setShelfCode(locationCode);
arr.setLightUpModel("常亮");
arrayList.add(arr);
});
lampDto.setControlList(arrayList);
numberLampMap.put(inputBillNumber, lampDto);
kafkaTemplate.send(Topic.Output.CONTROL_ELECLABEL, JSONObject.toJSONString(lampDto));
log.info("亮灯,topic:{}, data:{}", Topic.Output.CONTROL_ELECLABEL, JSONObject.toJSONString(lampDto));
log.info("开始发料:库位加数量"+materialAndLocationMap);
staticMaterialMap.put(inputBillNumber, materialMap);
staticMaterialAndLocationMap.put(inputBillNumber, materialAndLocationMap);
return getColorStr(color);
}
private Integer getColor(String pickBillNumber) {
Integer color = numberColorMap.get(pickBillNumber);
if (color == null || color == 0) {
color = getNextColor();
numberColorMap.put(pickBillNumber, color);
}
return color;
}
private static Integer getNextColor() {
colorIndex++;
if (colorIndex >= 8) {
colorIndex = 1;
}
if (numberColorMap.values().size() >= 7) {
throw new ServiceException(RespondEnum.FAILURE, "亮灯颜色最多为7种");
}
if (numberColorMap.values().contains(colorIndex)) {
return getNextColor();
} else {
return colorIndex;
}
}
private String getColorStr(Integer color) {
switch (color) {
case 1:
return "红";
case 2:
return "绿";
case 3:
return "黄";
case 4:
return "蓝";
case 5:
return "紫";
case 6:
return "青";
case 7:
return "白";
default:
return "";
}
}
/**
* 红字拆分
*/
@Transactional
public com.cmeim.stock.dto.MaterialBarDto inputStockInRedSplit(String number, String materialBar, BigDecimal backQty) {
String by = SecurityUtils.getUsername();
String currentDate = DateUtil.getCurrentDate();
log.info("红字拆分(单据号/条码/拆分数量)"+number+"/"+materialBar+"/"+backQty);
// 条码
MmMaterialBar mmMaterialBar = materialBarRepository.findByMaterialBar(materialBar);
if (mmMaterialBar == null) {
throw new ServiceException(RespondEnum.FAILURE, String.format("查询条码【%s】失败", materialBar));
}
if (backQty == null || backQty.abs().compareTo(BigDecimal.ZERO) == 0) {
throw new ServiceException(RespondEnum.FAILURE, String.format("拆分数量【%s】为空无法拆分",backQty.abs()));
}
if (mmMaterialBar.getMaterialQty().compareTo(backQty.abs()) < 0) {
throw new ServiceException(RespondEnum.FAILURE, String.format("拆分数量【%s】大于条码数量【%s】无法拆分",backQty.abs(),mmMaterialBar.getMaterialQty()));
}
com.cmeim.stock.dto.MaterialBarDto materialBarDto = BeanUtil.copyProperties(mmMaterialBar, com.cmeim.stock.dto.MaterialBarDto.class);
MmInputBill mmInputBill = mmInputBillRepository.findByInputBillNumber(number);
if (mmInputBill != null && StringUtils.isNotBlank(mmInputBill.getErpNumber())) {
throw new ServiceException(RespondEnum.FAILURE, String.format("红字入库单【%s】已上传ERP,无法拆分", number));
}
MmInputBillDetail detail =
inputBillDetailRepository.findByInputBillNumberAndMaterialCode(number,materialBarDto.getMaterialCode());
BigDecimal excessQty = backQty;
MmMaterialBar mmMaterialBarSplit = null;
//判断如果数量一致,走撤回逻辑,不需要拆分条码
if (mmMaterialBar.getMaterialQty().compareTo(backQty.abs()) != 0) {
//拆分线边仓条码
CreateBar createBar = new CreateBar();
createBar.setMaterialBar(mmMaterialBar.getMaterialBar());
createBar.setOldQty(mmMaterialBar.getMaterialQty());
createBar.setNewQty(excessQty.abs());
createBar.setPrefix("P");
createBar.setBarDictType(5);
mmMaterialBarSplit = materialBarService.splitMaterialBar(createBar);
}
//判断是否有拆分条码,或者数量一致
if (mmMaterialBarSplit != null || mmMaterialBar.getMaterialQty().compareTo(backQty.abs()) == 0) {
//调用库存入库PUML
StockInVo stockInVo = new StockInVo();
stockInVo.setMaterialBar(mmMaterialBar.getMaterialBar());
stockInVo.setMaterialDto(inputRemoteService.findMaterialDtoById(mmMaterialBar.getMaterialId()).getData());
stockInVo.setBatchNo(mmMaterialBar.getBatchNo());
stockInVo.setQty(excessQty.abs());
stockInVo.setBillId(detail.getId());
stockInVo.setBillNumber(detail.getInputBillNumber());
stockInVo.setDictBizType(49);
//判断数量一致就是撤回功能,事物类型为56
if (mmMaterialBar.getMaterialQty().compareTo(backQty.abs()) == 0) {
stockInVo.setDictBizType(56);
}
BaWarehouse targetBaWarehouse = baWareHouseRepository.findByWarehouseCode(mmInputBill.getWarehouseCode());
stockInVo.setFromBaWarehouse(targetBaWarehouse);
stockInVo.setFromWarehouseType(10);
stockInVo.setFromBaLocation(balocationRepository.findByLocationCode("LLCFKW"));
stockInVo.setTargetBaWarehouse(targetBaWarehouse);
stockInVo.setTargetWarehouseType(10);
stockInVo.setTargetBaLocation(balocationRepository.findByLocationCode("LLCFKW"));
stockInVo.setDictBilltype(55);
stockInVo.setUserName(by);
stockService.stockIn(stockInVo, false, false);
if (mmMaterialBarSplit != null && com.cmeim.common.core.utils.StringUtils.isNotBlank(mmMaterialBarSplit.getWarehouseCode())) {
BaWarehouse baWarehouse = baWareHouseRepository.findByWarehouseCode(mmMaterialBarSplit.getWarehouseCode());
if (baWarehouse != null && com.cmeim.common.core.utils.StringUtils.isNotBlank(baWarehouse.getCustomerAbbreviation())) {
mmMaterialBarSplit.setCustomerAbbreviation(baWarehouse.getCustomerAbbreviation());
}
}
MmInputBillItem mItem = mmInputBillItemRepository.findByInputBillNumberAndMaterialBar(number, materialBar);
//拆分逻辑走
if (mItem != null && mmMaterialBar.getMaterialQty().compareTo(backQty.abs()) != 0) {
mItem.setMaterialBar(mmMaterialBarSplit.getMaterialBar());
mItem.setQty(mmMaterialBarSplit.getMaterialQty());
mItem.setUpdatedBy(by);
mItem.setUpdatedDt(currentDate);
log.info("红字拆分之后把领料记录条码进行修改改成:"+mItem);
mmInputBillItemRepository.save(mItem);
}
//撤回逻辑走
if (mItem != null && mmMaterialBar.getMaterialQty().compareTo(backQty.abs()) == 0) {
mmInputBillItemRepository.delete(mItem);
}
}
detail.setRealQty(detail.getRealQty().add(excessQty.abs()));
detail.setDictStatus(23);
detail.setUpdatedBy(by);
detail.setUpdatedDt(currentDate);
log.info("红字入库拆分回写入库单明细数据:"+detail);
inputBillDetailRepository.save(detail);
log.info("红字拆分出来数据:"+mmMaterialBarSplit);
if (mmMaterialBarSplit != null) {
return BeanUtil.copyProperties(mmMaterialBarSplit, MaterialBarDto.class);
}
return new MaterialBarDto();
}
public void redOff(String number) {
// 全灭
WCSStoreLampVo lampDto = numberLampMap.get(number);
if (lampDto == null) {
return;
}
lampDto.getControlList().forEach(arr -> {
arr.setLightUpModel("关闭");
});
kafkaTemplate.send(Topic.Output.CONTROL_ELECLABEL, JSONObject.toJSONString(lampDto));
log.info("全灭熄灯,topic:{}, data:{}", Topic.Output.CONTROL_ELECLABEL, JSONObject.toJSONString(lampDto));
numberColorMap.remove(number);
numberLampMap.remove(number);
}
public List<InputBillDetailVo> findByInputNumber(String number, Integer[] dictStatus, String materialCode) {
List<MmInputBillDetail> detail = this.findDetailByInputBillNumber(number, dictStatus, materialCode);
List<InputBillDetailVo> voList = BeanUtil.copyProperties(detail, InputBillDetailVo.class);
List<String> collect = voList.stream().map(InputBillDetailVo::getMaterialCode).collect(Collectors.toList());
List<MmInputBillItem> items = mmInputBillItemRepository.findByInputBillNumberAndMaterialCodeIn(number, collect);
voList.forEach(vo -> {
/* findByPickNumberSplit(vo);*/
// 查询相关领料记录
vo.setItems(items.stream().filter(s ->s.getMaterialCode().equals(vo.getMaterialCode())).collect(Collectors.toList()));
});
return voList;
}
/**
* findDetailByPickBillNumber
*/
@Transactional
public List<MmInputBillDetail> findDetailByInputBillNumber(String number, Integer[] dictStatus, String materialCode) {
MmInputBillDetail mmPickBillDetail = new MmInputBillDetail();
mmPickBillDetail.setInputBillNumber(number);
mmPickBillDetail.setMaterialCode(materialCode);
return inputBillDetailRepository.findAll(buildSpecifications(mmPickBillDetail, dictStatus));
}
private Specification buildSpecifications(MmInputBillDetail entity, Integer[] dictStatus) {
Specification specification = (Specification<MmInputBillDetail>) (root, criteriaQuery, cb) -> {
List<Predicate> predicates = Lists.newArrayList();
if (StringUtils.isNotBlank(entity.getMaterialCode())) {
predicates.add(cb.like(root.get("materialCode").as(String.class), "%" + entity.getMaterialCode() + "%"));
}
if (StringUtils.isNotBlank(entity.getInputBillNumber())) {
predicates.add(cb.equal(root.get("inputBillNumber").as(String.class), entity.getInputBillNumber()));
}
if (dictStatus != null) {
CriteriaBuilder.In<Integer> in = cb.in(root.get("dictStatus").as(Integer.class));
for (Integer order : dictStatus) {
in.value(order);
}
predicates.add(in);
}
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
};
return specification;
}
}