Commit c80451cc sunke

成本中心领料-大于等于需求量最小的料盘数量

线边仓间转储出库,转外协出库,发运单出库-整盘优先原则,不足发散盘
已使用库位加入缓存
产线补料出库BUG修正
1 个父辈 ad6cd77e
......@@ -45,7 +45,7 @@ public class DataInitManager {
MainTimer mainTimer;
//@Value("${menu.show}")
private String[] menuShowList = new String[]{"productionLineReple","productionLineOut"};
private String[] menuShowList = new String[]{"productionLineReple","productionLineOut","interfaceException"};
//@Value("${menu.hide}")
private String[] menuHideList = new String[]{};
......
......@@ -29,6 +29,7 @@ import com.neotel.smfcore.security.TokenProvider;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
......@@ -52,71 +53,6 @@ public class NLPShelfHandler extends BaseDeviceHandler{
super(apiList);
}
// /**
// * 扫码
// */
// @ApiOperation("扫码入库")
// @PostMapping("/api/sensorShelf/codeIn")
// @PreAuthorize("@el.check('sensorShelf:putIn')")
// public ResultBean codeIn( @RequestBody Map<String, String> mapValues,HttpServletRequest request) {
// String code = mapValues.get("code");
// String groupId = mapValues.get("group");
// String storageId=mapValues.get("storageId");
// String sourceId=mapValues.get("sourceId");
// String token = tokenProvider.getToken(request);
// if(ObjectUtils.isEmpty(code)){
// throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"code"});
// }
// if(groupId==null&&storageId==null){
// throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"group"});
// }
// if(groupId==null&&storageId!=null){
// Storage storage=dataCache.getStorageById(storageId);
// if(storage!=null){
// groupId=storage.getGroupId();
// }
// }
// if(groupId!=null&&groupId.equals("-1")){
// groupId="";
// }
// // WebSocketServer.sendMsg("", new SocketMsg("{0}未找到库位:{1}"+code, MsgType.INFO,"smfclient.nlp.cannotFindPos",new String[]{"消息测试","库位号"}));
// String loginUser = SecurityUtils.getLoginUsername();
// Collection<DataLog> queueTasks = taskService.getQueueTasks();
// ResultBean resultBean = null;
// for (DataLog queueTask : queueTasks) {
// if (queueTask.isPutInTask() && queueTask.isWait()) {
// if (!Strings.isNullOrEmpty(groupId) && queueTask.getGroupId().equals(groupId)) {
// log.info("codeIn [" + code + "][" + groupId + "]入库失败:条码[" + queueTask.getBarcode() + "]的任务还未结束 ");
// throw new ValidateException("smfcore.unfinished", "the task of [{0}] is unfinished", new String[]{queueTask.getBarcode()});
// }
// if (!Strings.isNullOrEmpty(storageId) && queueTask.getStorageId().equals(storageId)) {
// log.info("codeIn [" + code + "][" + storageId + "]入库失败:条码[" + queueTask.getBarcode() + "]的任务还未结束 ");
// throw new ValidateException("smfcore.unfinished", "the task of [{0}] is unfinished", new String[]{queueTask.getBarcode()});
// }
// }
// }
//
// Barcode barcodeSave = resolveBarcodeFromApiForShelf(new CodeValidateParam( loginUser,groupId,storageId,code,token));
// if(barcodeSave == null){
// barcodeSave = codeResolve.resolveOneValideBarcode("=1x1="+code);
// }
//
// Date expireDate = barcodeSave.getExpireDate();
// if (expireDate != null) {
// if (System.currentTimeMillis() > expireDate.getTime()) {
// throw new ValidateException("smfcore.error.barcode.expired", "物料已过期,无法入库.");
// }
// }
//
// //从API验证
// Barcode verResult = verifyPutInFromApi(barcodeSave);
//
// if(verResult==null){
// return testPutIn(loginUser,groupId,storageId, barcodeSave,token);
// }
//// resultBean = hellaServiceHandler.checkMaterial(loginUser, groupId, code);
// return ResultBean.newOkResult("");
// }
private ResultBean testPutIn(String loginUser, String groupId,String storageId,Barcode barcode,String token) {
......@@ -226,11 +162,12 @@ public class NLPShelfHandler extends BaseDeviceHandler{
}
}
if (color != null) {
queueTask.setStatus(OP_STATUS.EXECUTING.name());
taskService.updateQueueTask(queueTask);
statusBean.addData("open", queueTask.getPosName() + "=" + color.name());
log.info("库位[" + queueTask.getPosName() + "]["+queueTask.getBarcode()+"]+亮灯:" + color.name());
if(Strings.isNotBlank(queueTask.getPosName())){
statusBean.addData("open", queueTask.getPosName() + "=" + color.name());
log.info("库位[" + queueTask.getPosName() + "]["+queueTask.getBarcode()+"]+亮灯:" + color.name());
}
}
}
// else if(queueTask.isCancel()){
......@@ -277,21 +214,9 @@ public class NLPShelfHandler extends BaseDeviceHandler{
noReelPosErrorList = new String[]{};
}
List<String> ngToOk=new ArrayList<>();
// //数据库无信息,实际有料
// if(hasReelPosErrorList.length>0){
// Query query=new Query(Criteria.where("posName").in(hasReelPosErrorList));
// List<StoragePos> posList= storagePosManager.findByQuery(query);
// for (StoragePos pos:posList
// ) {
// if(pos.isUsed()){
// ngToOk.add(pos.getPosName());
// log.info("sensorChange 客户端上传 hasReelPosErrorList 库位["+pos.getPosName()+"]数据库有信息,放入ngToOk");
// }
// }
// }
//数据库有信息,实际无料
if(noReelPosErrorList.length>0){
log.info("开始检测noReelPosErrorList");
Query query=new Query(Criteria.where("posName").in(noReelPosErrorList));
List<StoragePos> posList= storagePosManager.findByQuery(query);
for (StoragePos pos:posList) {
......@@ -313,6 +238,7 @@ public class NLPShelfHandler extends BaseDeviceHandler{
List<String> outNgList = new ArrayList<>();
if(hasReelPosList != null){
log.info("开始检测hasReelPosList");
List<String> newList=new ArrayList<>();
for (String posName : hasReelPosList) {
StoragePos pos = storagePosManager.getByPosName(posName);
......@@ -337,6 +263,7 @@ public class NLPShelfHandler extends BaseDeviceHandler{
inNgList.add(posStr);
}
}else if (hasReelPosList.length==1){
log.info("开始检测执行入库");
StoragePos pos = storagePosManager.getByPosName(hasReelPosList[0]);
if(pos == null){
String msg = "未找到库位:"+String.join(",",hasReelPosList) ;
......@@ -372,15 +299,17 @@ public class NLPShelfHandler extends BaseDeviceHandler{
queueTask.setStorageName(storage.getName());
try {
//入库完成,发送入库完成请求
log.info("入库完成,发送入库完成请求");
super.finishedPutIn(cid, pos.getPosName());
inOkList.add(hasReelPosList[0]);
String msg = queueTask.getBarcode() + "入库到" + pos.getPosName() + "成功";
log.error(msg);
log.info(msg);
WebSocketServer.sendMsg("",new SocketMsg(msg, MsgType.INFO,"smfclient.nlp.inputOk",new String[]{queueTask.getBarcode(),pos.getPosName()}));
try {
//判断是否是入库单入库
if (queueTask.getInType() == 5) {
log.info("入库单入库");
Barcode barcode = barcodeManager.findByBarcode(queueTask.getBarcode());
InListItem item = inListCache.UpdateInList(queueTask.getSourceName(), pos, barcode);
......@@ -392,6 +321,8 @@ public class NLPShelfHandler extends BaseDeviceHandler{
}
} else {
log.info("调用 7.5入库上架过账接口");
//入库完成,调用 7.5入库上架过账接口
boolean result = HikApi.putInApi(queueTask.getOperator(), InOutApiInfo.inputInfo(queueTask.getInType(), queueTask.getBarcode(), queueTask.getNum()));
......@@ -419,6 +350,8 @@ public class NLPShelfHandler extends BaseDeviceHandler{
}
if(noReelPosList != null){
//出库
log.info("出库检测noReelPosList");
for (String posName : noReelPosList) {
StoragePos pos = storagePosManager.getByPosName(posName);
if(pos==null){
......@@ -490,16 +423,7 @@ public class NLPShelfHandler extends BaseDeviceHandler{
@AnonymousAccess
public ResultBean shelfStatus(HttpServletRequest request){
String cid = request.getParameter("cid");
Storage storage = dataCache.getStorage(cid);
if(storage == null){
return ResultBean.newErrorResult(-1,"smfcore.shelfNotExist", "{0}对应的料架不存在",new String[]{cid} );
}
List<StoragePos> allPos = storagePosManager.findNotEmptyByStorageId(storage.getId());
List<String> posList = new ArrayList<>();
for (StoragePos pos : allPos) {
posList.add(pos.getPosName());
}
List<String> posList = dataCache.getUsedPosNameList(cid);
List<String> outTaskPosList = new ArrayList<>();
Collection<DataLog> queueTasks = taskService.getQueueTasks(cid);
for (DataLog task : queueTasks) {
......@@ -518,6 +442,7 @@ public class NLPShelfHandler extends BaseDeviceHandler{
Map<String,List<String>> dataMap = new HashMap<>();
dataMap.put("hasReelPosList",posList);
dataMap.put("outTaskList",outTaskPosList);
//log.info("客户端获取["+cid+"]库位占用情况返回");
return ResultBean.newOkResult(dataMap);
}
......@@ -529,15 +454,7 @@ public class NLPShelfHandler extends BaseDeviceHandler{
@AnonymousAccess
public ResultBean checkAll(HttpServletRequest request){
String cid = request.getParameter("cid");
Storage storage = dataCache.getStorage(cid);
if(storage == null){
return ResultBean.newErrorResult(-1,"smfcore.shelfNotExist", "{0}对应的料架不存在",new String[]{cid} );
}
List<StoragePos> allPos = storagePosManager.findNotEmptyByStorageId(storage.getId());
List<String> posList = new ArrayList<>();
for (StoragePos pos : allPos) {
posList.add(pos.getPosName());
}
List<String> posList = dataCache.getUsedPosNameList(cid);
return ResultBean.newOkResult(posList);
}
@Override
......
......@@ -270,6 +270,10 @@ public class DataCache {
*/
private static Map<String,Map<String,InventoryItem>> inventoryMap = new ConcurrentHashMap<>();
/**
* 库位占用Map, key为cid,value为已使用的库位列表
*/
private static Map<String,List<String>> usedPosNameMap = new ConcurrentHashMap<>();
/**
......@@ -518,6 +522,44 @@ public class DataCache {
}
/**
* 出库时清除使用库位列表
*/
private void removeUsedPosNameList(String cid, String posName){
List<String> usedPosNameList = getUsedPosNameList(cid);
usedPosNameList.remove(posName);
usedPosNameMap.put(cid, usedPosNameList);
}
/**
* 入库时增加使用库位列表
*/
private void addUsedPosNameList(String cid, String posName){
List<String> usedPosNameList = getUsedPosNameList(cid);
usedPosNameList.add(posName);
usedPosNameMap.put(cid, usedPosNameList);
}
/**
* 获取设备所有占用的库位名称列表
*/
public List<String> getUsedPosNameList(String cid){
List<String> posNameList = usedPosNameMap.get(cid);
if(posNameList == null){
Storage storage = getStorage(cid);
posNameList = new ArrayList<>();
if(storage != null){
log.info("加载["+cid+"]所有已使用库位到缓存");
List<StoragePos> allPos = storagePosManager.findNotEmptyByStorageId(storage.getId());
for (StoragePos pos : allPos) {
posNameList.add(pos.getPosName());
}
usedPosNameMap.put(cid,posNameList);
}
}
return posNameList;
}
public InventoryItem getStorageInventoryByPartNumber(String cid, String partNumber){
Map<String, InventoryItem> storageInventory = getStorageInventory(cid);
InventoryItem partNumberInventoryItem = storageInventory.get(partNumber);
......@@ -558,7 +600,7 @@ public class DataCache {
* @param amount
* @return
*/
public int updateInventoryAmount(String cid,String partNumber,int amount){
private int updateInventoryAmount(String cid,String partNumber,int amount){
if(amount != 0){
InventoryItem inventoryItem = getStorageInventoryByPartNumber(cid,partNumber);
if(inventoryItem == null){
......@@ -586,11 +628,12 @@ public class DataCache {
//出库
amount = - barcode.getAmount();
storage.emptyOnePos(pos);
removeUsedPosNameList(cid, pos.getPosName());
}else{
//入库
amount = barcode.getAmount();
storage.useOnePos(pos);
addUsedPosNameList(cid, pos.getPosName());
//入库单处理
if(ObjectUtil.isNotEmpty(storage.getInListName())){
inListCache.UpdateInList(storage.getInListName(),pos,barcode);
......
......@@ -42,8 +42,7 @@ public class LanguageMsgService {
int hasCount=1;
Map<String,Map<String, LanguageMsg>> resourceMap=new HashMap<>();
List<LanguageMsg> msgs = languageMsgManager.findByQuery(new Query());
for (LanguageMsg msg :
msgs) {
for (LanguageMsg msg : msgs) {
if(msg.getCode().startsWith("smfcode.")||msg.getType().equals("smfcode")){
String newCode=msg.getCode().replace("smfcode.","smfcore.");
msg.setCode(newCode);
......@@ -235,10 +234,8 @@ public class LanguageMsgService {
List<LanguageMsg> newLanguageList = new ArrayList<>();
List<LanguageMsg> updateLanguageList = new ArrayList<>();
if (proMap != null && proMap.size() > 0) {
for (String key :
proMap.keySet()) {
for (String key : proMap.keySet()) {
//如果Key爲空,直接返回
if(ObjectUtil.isEmpty(key))
{
......@@ -273,8 +270,7 @@ public class LanguageMsgService {
if (newLanguageList.size() > 0) {
languageMsgManager.insertAll(newLanguageList);
for (LanguageMsg msg :
newLanguageList) {
for (LanguageMsg msg : newLanguageList) {
MessageUtils.updateMsg(msg);
}
}
......
......@@ -283,6 +283,15 @@ public class LiteOrderCache implements ITaskListener {
newItems = (ArrayList<HikOrderInfo>) apiResult.getData();
}
}
// newItems = Lists.newArrayList();
// HikOrderInfo item = new HikOrderInfo();
// item.setBaseCode("BaseCode");
// item.setQty(1000);
// item.setMaterialNo("100100704");
// item.setStation("AAA");
// item.setJobNo("1001583501_1");
// item.setReplenishmentNo("8001B22070600061");
// newItems.add(item);
if (newItems != null) {
//删除旧的Items
......@@ -439,13 +448,12 @@ public class LiteOrderCache implements ITaskListener {
boolean needJieliao =false;
//查找PN的所有库存,PN=pn,未锁定,qty 从大到小,入库时间正序
//查找PN的所有库存,PN=pn,未锁定,qty 从大到小,批次正序, 入库时间正序
List<StoragePos> posList = storagePosManager.findOrderItemInStorage(availableStorageIds, pn, excludePosIds);
int storageNum=0;
int reelNum=posList.size();
for (StoragePos pos :posList
) {
for (StoragePos pos :posList) {
storageNum+=pos.getBarcode().getAmount();
}
......@@ -455,9 +463,9 @@ public class LiteOrderCache implements ITaskListener {
log.info("工单[" + cacheOrder.getOrderNo() + "]缺料出库: 物料号[" + pn + "] ,需求数量[" + orderItem.getWemng() + "], 未找到元器件信息 ");
shortage = true;
//判断库存 使用最小库存盘数:当前盘数<=最小库存盘数时,需要截料
if(component.getMinStoreNum()>0&& reelNum<=component.getMinStoreNum()){
needJieliao=true;
}
// if(component.getMinStoreNum()>0&& reelNum<=component.getMinStoreNum()){
// needJieliao=true;
// }
}else {
log.info("工单[" + cacheOrder.getOrderNo() + "] 物料号[" + pn + "] ,需求数量[" + orderItem.getWemng() + "], 未找到元器件信息, 缺料 ");
return materialShortPro(userName, cacheOrder);
......@@ -488,15 +496,18 @@ public class LiteOrderCache implements ITaskListener {
}
}
//判断库存 使用最小库存盘数:当前盘数<=最小库存盘数时,需要截料
if(component.getMinStoreNum()>0&& reelNum<=component.getMinStoreNum()){
needJieliao=true;
}
List<StoragePos> itemPosList = new ArrayList<>();
List<String> itemPosNameList = new ArrayList<>();
//此PN未完成
int targetNum = needNum;
for (int i=0;i<posList.size();i++
) {
for (int i=0;i<posList.size();i++) {
List<StoragePos> forPosList=new ArrayList<>();
for (StoragePos pos :
posList) {
for (StoragePos pos : posList) {
if(!itemPosNameList.contains(pos.getPosName())){
forPosList.add(pos);
}
......@@ -504,8 +515,7 @@ public class LiteOrderCache implements ITaskListener {
//循环剩余的库位,查找
int forIndex=-1;
for (StoragePos pos :
forPosList) {
for (StoragePos pos : forPosList) {
forIndex++;
boolean isLast=(forIndex==(forPosList.size()-1));
//已经在出库列表
......@@ -621,6 +631,9 @@ public class LiteOrderCache implements ITaskListener {
int itemReelCount=0;
int itemOutCount=0;
List<StoragePos> posList=needOutPosMap.get(orderItem.getMaterialNo());
if(posList == null){
posList = new ArrayList<>();
}
for (StoragePos pos : posList) {
DataLog task = taskService.newTask(pos) ;
......@@ -650,7 +663,12 @@ public class LiteOrderCache implements ITaskListener {
if(addOutbound){
task.setInOperate(true);
task.setAddOutbound(true);
task.setLightColor(ORDER_COLOR.PINK.getRgb());//补料出库 颜色:PINK
task.setLightColor(ORDER_COLOR.PINK.getRgb());//缺料出库 颜色:PINK
}
if(cacheOrder.isRepleOrder()){
//产线补料
task.setLightColor(ORDER_COLOR.FORESTGREEN.getRgb());//产线补料出库 颜色:FORESTGREEN
}
try{
taskService.addTaskToExecute(task);
......
......@@ -29,6 +29,10 @@ public enum ORDER_COLOR {
// 'white':[15,125,125,125],
// 'off':[16,0,0,0],
// 'magenta':[17,125,125,0]
//手动出库:BLUE;入库:DARKGREEN;
// 工单首盘料:CYAN;工单截料:PURPLE;工单备件:SKYBLUE;
// 工单缺料出库:PINK;普通转储出库单:FIREBRICK;产线实料出库 颜色:FORESTGREEN
BLUE("0000FF"),
//MAGENTA("FF00FF"),
CYAN("00FFFF"),
......@@ -37,8 +41,8 @@ public enum ORDER_COLOR {
SKYBLUE("6CA6CD"),
PINK("FF1493"),
FORESTGREEN("228B22"),
LIGHTBLUE("8470FF"),
INDIANRED("8B3A3A"),
LIGHTBLUE("8470FF"),//暂时未使用
INDIANRED("8B3A3A"),//暂时未使用
DARKGREEN("556B2F"),
;
......
......@@ -212,7 +212,7 @@ public class RepleOrderController {
@ApiOperation("料盘出库界面,获取执行的工单列表")
@GetMapping("/executeOrders")
@PreAuthorize("@el.check('reelOut')")
@PreAuthorize("@el.check('productionLineReple')")
public List<OrderDto> queryExecuteOrder() {
//查询正在执行的工单列表
Query query = new Query(Criteria.where("status").is(LITEORDER_STATUS.EXECUTING).and("replenishmentNo").ne(null));
......@@ -252,7 +252,7 @@ public class RepleOrderController {
@ApiOperation("料盘出库界面,获取当前产线补料任务列表")
@GetMapping("/reelOutTasks")
@PreAuthorize("@el.check('reelOut')")
@PreAuthorize("@el.check('productionLineReple')")
public List<TaskDto> queryReelOutTasks(@RequestParam Map<String, String> paramsMap) {
//查询正在执行的工单列表
......@@ -276,7 +276,7 @@ public class RepleOrderController {
@ApiOperation("料盘出库界面,切换到下一个工单")
@PostMapping("/nextOrder")
@PreAuthorize("@el.check('reelOut')")
@PreAuthorize("@el.check('productionLineReple')")
public ResultBean nextOrder(@RequestParam Map<String, String> paramsMap) {
if (ObjectUtil.isNotEmpty(currOrderNo)) {
......@@ -295,6 +295,7 @@ public class RepleOrderController {
}
LiteOrder liteOrder = orderList.get(0);
currOrderNo = liteOrder.getOrderNo();
//设置此工单的任务可以发送给料架
List<DataLog> taskList = getOrderTaskByUser(liteOrder, true);
for (DataLog datalog : taskList) {
......@@ -306,7 +307,7 @@ public class RepleOrderController {
}
@ApiOperation("齐套页面,获取齐套数据")
@GetMapping("/orderSet")
@PreAuthorize("@el.check('workOrder')")
@PreAuthorize("@el.check('productionLineReple')")
public List<OrderPnDto> orderSetData( ) {
List<OrderPnInfo> orderPnInfos=orderPnCache.getDataList();
......@@ -315,7 +316,7 @@ public class RepleOrderController {
}
@ApiOperation("齐套页面,刷新齐套数据")
@PostMapping("/orderSet/update")
@PreAuthorize("@el.check('workOrder')")
@PreAuthorize("@el.check('productionLineReple')")
public ResultBean updateOrderSet(HttpServletRequest request ) {
boolean result = orderPnCache.reloadData();
if (!result) {
......@@ -328,7 +329,7 @@ public class RepleOrderController {
@ApiOperation("导出齐套列表")
@GetMapping(value = "/orderSet/download")
@PreAuthorize("@el.check('workOrder')")
@PreAuthorize("@el.check('productionLineReple')")
public void download(HttpServletResponse response, HttpServletRequest request) throws IOException {
List<OrderPnInfo> orderPnInfos=orderPnCache.getDataList();
download(orderPnInfos,response,request.getLocale());
......@@ -353,7 +354,7 @@ public class RepleOrderController {
private List<LiteOrder> getExecuteOrders() {
//查询正在执行的工单列表
Query query = new Query(Criteria.where("status").is(LITEORDER_STATUS.EXECUTING).and("replenishmentNo").not());
Query query = new Query(Criteria.where("status").is(LITEORDER_STATUS.EXECUTING).and("replenishmentNo").ne(null));
//根据开始出库时间排序
Sort sort = Sort.by(Sort.Direction.ASC, "startOutTime");
query.with(sort);
......
......@@ -8,6 +8,7 @@ import com.neotel.smfcore.core.order.enums.LITEORDER_STATUS;
import com.neotel.smfcore.hikvision.bean.HikOrderInfo;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.mapping.Document;
......@@ -260,6 +261,15 @@ public class LiteOrder extends BasePo implements Serializable {
return status == LITEORDER_STATUS.ADDOUTBOUND;
}
/**
* 是否是产线补(有补料单号)
* @return
*/
public boolean isRepleOrder(){
//是否是产线补料
return Strings.isNotBlank(replenishmentNo);
}
public void setTaskReelCount(int taskReelCount) {
......
......@@ -270,23 +270,16 @@ public class OutListCache implements ITaskListener {
}
}
List<StoragePos> itemPosList = new ArrayList<>();
//此PN未完成
int targetNum = needNum;
int docType = outList.getDocType();
List<StoragePos> itemPosList = pickReels(docType,itemPosNameList,posList,targetNum);
//循环剩余的库位,查找
//int forIndex = -1;
for (StoragePos pos : posList) {
if(!itemPosNameList.contains(pos.getPosName())){
itemPosList.add(pos);
itemPosNameList.add(pos.getPosName());
targetNum -= pos.getBarcode().getAmount();
if (targetNum <= 0) {
break;
}
}
for (StoragePos storagePos : itemPosList) {
itemPosNameList.add(storagePos.getPosName());
targetNum -= storagePos.getBarcode().getAmount();
}
//判断数量是否满足
if (targetNum > 0) {
int outNum = needNum - targetNum;
......@@ -336,7 +329,7 @@ public class OutListCache implements ITaskListener {
task.setOutType(4);
}
task.setLightColor(ORDER_COLOR.SKYBLUE.getRgb());//普通转储出库单 颜色:SKYBLUE
task.setLightColor(ORDER_COLOR.FIREBRICK.getRgb());//普通转储出库单 颜色:FIREBRICK
taskService.addTaskToExecute(task);
log.info("转储出库单[" + name + "],任务数[" + taskReelCount + "]仓位【" + pos.getPosName() + "】RI=[" + pos.getBarcode().getBarcode() + "] PN=[" + outListItem.getMaterialNo() + "] Amount[" + pos.getBarcode().getAmount() +
"] 首盘[" + task.isFirstReel() + "] 截料[" + task.isNeedSplitting() + "][" + task.getNeedQty() + "]");
......@@ -374,5 +367,64 @@ public class OutListCache implements ITaskListener {
return "";
}
/**
* 1,成本中心领料-大于等于需求量最小的料盘数量
* 2,线边仓间转储出库,转外协出库,发运单出库-整盘优先原则,不足发散盘
*/
private List<StoragePos> pickReels(int docType, List<String> outPosNameList, List<StoragePos> posList, int targetNum){
List<String> excludePosNameList = new ArrayList<>(outPosNameList);
List<StoragePos> itemPickPosList = new ArrayList<>();
boolean pickMaxQtyReel = true;
if(docType == 3){
//1,成本中心领料-大于等于需求量最小的料盘数量
pickMaxQtyReel = false;
}else{
//2,线边仓间转储出库,转外协出库,发运单出库-整盘优先原则,不足发散盘
pickMaxQtyReel = true;
}
do {
StoragePos outPos = pickOneReel(excludePosNameList,posList,targetNum, pickMaxQtyReel);
if(outPos == null){
break;
}else{
log.info("挑选到批次["+outPos.getBarcode().getBatch()+"]物料:" + outPos.getBarcode().getBarcode() + " 数量:" + outPos.getBarcode().getAmount());
itemPickPosList.add(outPos);
excludePosNameList.add(outPos.getPosName());
targetNum = targetNum - outPos.getBarcode().getAmount();
if(targetNum <=0){
break;
}
}
} while(true);
return itemPickPosList;
}
private StoragePos pickOneReel(List<String> excluedPosNameList, List<StoragePos> posList, int targetNum, boolean pickMaxQtyReel){
StoragePos outPos = null;
if(targetNum > 0){
for (StoragePos pos : posList) {
if(!excluedPosNameList.contains(pos.getPosName())){
if(outPos == null){
//先取第一盘(数量最大的盘)
outPos = pos;
if(pickMaxQtyReel){
return outPos;
}
}
int qty = pos.getBarcode().getAmount();
if(qty < outPos.getBarcode().getAmount() && qty >= targetNum){
//如果当前盘小于已挑料盘并且这盘料出库后可以满足需求,那么替换已挑料盘
outPos = pos;
}
if(qty < targetNum){
//当前料盘挑完还不满足需求
return outPos;
}
}
}
}
return outPos;
}
}
......@@ -600,9 +600,9 @@ public class StoragePosManagerImpl implements IStoragePosManager {
}
Query q = new Query(c);
//数量从大到小,出库先进先出
Sort sort = Sort.by(Sort.Direction.ASC, "barcode.amount");
Sort sort = Sort.by(Sort.Direction.DESC, "barcode.amount");
sort.and(Sort.by(Sort.Direction.ASC, "barcode.batch"));
sort.and(Sort.by(Sort.Direction.ASC, "canCheckOutTime"));
//sort.and(Sort.by(Sort.Direction.ASC, "canCheckOutTime"));
q.with(sort);
List<StoragePos> posList = storagePosDao.findByQuery(q);
if (posList == null || posList.size() <= 0) {
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!