964 lines
39 KiB
Plaintext
964 lines
39 KiB
Plaintext
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;
|
||
}
|
||
}
|