Commit 4ed50f7b LN

增加工单合单功能

1 个父辈 148fd00f
package com.neotel.smfcore.core.order.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class OrderBoxInfo implements Serializable {
/**
* 操作人
*/
private String operater;
/**
* 箱子名
*/
private String boxName;
}
package com.neotel.smfcore.core.order.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class OrderPosInfo implements Serializable {
/**
* 位置名字
*/
private String position;
/**
* 位置类型:1=首料,2=截料,3=备料,4=欠料
*/
private int type;
}
......@@ -314,7 +314,7 @@ public class OrderController {
Sort sort = Sort.by(Sort.Direction.ASC, "startOutTime");
query.with(sort);
List<LiteOrder> orderList = liteOrderManager.findByQuery(query);
List<OrderDto> resultList = orderMapper.toDto(orderList);
List<OrderDto> resultList =new ArrayList<>();
boolean findOrder = false;
//只返回当前有任务的工单
......@@ -382,7 +382,7 @@ public class OrderController {
LiteOrder preOrder = liteOrderCache.findOrderByNo(user.getCurrOrderNo());
List<DataLog> preTasks = getOrderTaskByUser(user, preOrder, true);
if (preTasks.size() > 0) {
return ResultBean.newErrorResult(-1, "smfcore.order.preNotEnd", "工单[" + preOrder + "]还有[" + preTasks.size() + "]个出库任务未结束",
return ResultBean.newErrorResult(-1, "smfcore.order.preNotEnd", "工单[" + preOrder.getOrderNo() + "]还有[" + preTasks.size() + "]个出库任务未结束",
new String[]{user.getCurrOrderNo(), preTasks.size() + ""});
}
}
......@@ -483,9 +483,14 @@ public class OrderController {
}
//查询正在执行的工单列表
List<String> myStorageIds = new ArrayList<>();
if (user != null) {
Set<String> groupIds=user.getGroups();
if(user.getUsername().equals(Constants.SUPER_USERNAME)){
groupIds.add("");
}
for (String groupId :
user.getGroups()) {
groupIds) {
List<String> storageIds = dataCache.getStorageIdsByGroupId(groupId, false);
myStorageIds.addAll(storageIds);
}
......
package com.neotel.smfcore.core.order.rest;
import cn.hutool.core.util.ObjectUtil;
import com.google.common.collect.Lists;
import com.neotel.smfcore.common.bean.PageData;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.QueryHelp;
import com.neotel.smfcore.common.utils.SecurityUtils;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.barcode.utils.CodeResolve;
import com.neotel.smfcore.core.barcode.utils.QrcodeUtils;
import com.neotel.smfcore.core.order.LiteOrderCache;
import com.neotel.smfcore.core.order.bean.OrderBoxInfo;
import com.neotel.smfcore.core.order.bean.OrderPosInfo;
import com.neotel.smfcore.core.order.enums.LITEORDER_STATUS;
import com.neotel.smfcore.core.order.rest.bean.dto.OrderDto;
import com.neotel.smfcore.core.order.rest.bean.dto.OrderRIPostDto;
import com.neotel.smfcore.core.order.rest.bean.mapstruct.OrderMapper;
import com.neotel.smfcore.core.order.rest.bean.query.OrderQueryCondition;
import com.neotel.smfcore.core.order.service.manager.ILiteOrderManager;
import com.neotel.smfcore.core.order.service.po.LiteOrder;
import com.neotel.smfcore.core.system.service.manager.IDataLogManager;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.security.service.manager.IGroupManager;
import com.neotel.smfcore.security.service.manager.IUserManager;
import com.neotel.smfcore.security.service.po.Group;
import com.neotel.smfcore.security.service.po.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Slf4j
@Api(tags = "工单合单")
@RestController
@RequestMapping("/api/orderSheet")
@RequiredArgsConstructor
public class OrderSheetController {
@Autowired
private ILiteOrderManager liteOrderManager;
@Autowired
private LiteOrderCache liteOrderCache;
@Autowired
private IUserManager userManager;
@Autowired
private IGroupManager groupManager;
@Autowired
private IDataLogManager dataLogManager;
@Autowired
private final OrderMapper orderMapper;
@Autowired
protected CodeResolve codeResolve;
@ApiOperation("绑定箱子")
@PostMapping(value = "/bindBox")
@PreAuthorize("@el.check('workOrder')")
public ResultBean bindBox(@RequestBody Map<String, Object> mapValues) {
String orderNo = mapValues.get("orderNo").toString();
List<String> boxNames = (List<String>) mapValues.get("boxInfos");
if (orderNo == null) {
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"orderNo"});
}
LiteOrder liteOrder = liteOrderManager.findByOrderNo(orderNo);
if (liteOrder == null) {
throw new ValidateException("smfcore.valueNotFind", "未找到{0}[{1}]", new String[]{"orderNo", orderNo});
}
if (boxNames == null || boxNames.size() <= 0) {
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"boxInfos"});
}
for (String boxName :
boxNames) {
if (liteOrder.hasBox(boxName)) {
throw new ValidateException("smfcore.orderSheet.box.exists", "工单{0}已存在箱子{0}", new String[]{liteOrder.getOrderNo(), boxName});
}
}
for (String boxName :
boxNames) {
OrderBoxInfo boxInfo = new OrderBoxInfo(SecurityUtils.getCurrentUsername(), boxName);
liteOrder.addBox(boxInfo);
}
liteOrderManager.save(liteOrder);
liteOrderCache.addOrderToMap(liteOrder);
return ResultBean.newOkResult("smfcore.orderSheet.box.bindOk", "绑定成功", "");
}
@ApiOperation("工单合单列表")
@GetMapping(value = "/list")
@PreAuthorize("@el.check('workOrder')")
public PageData<OrderDto> queryList(OrderQueryCondition criteria, Pageable pageable) {
User user = userManager.findByUserName(SecurityUtils.getCurrentUsername());
if (user != null) {
//数据权限 查找没有权限的组列表
if (!user.getIsAdmin()) {
Set<String> groupIds = user.getGroups();
List<String> excludeSources = Lists.newArrayList();
List<Group> groups = groupManager.findAll();
for (Group group :
groups) {
if (groupIds.contains(group.getId())) {
continue;
}
excludeSources.add(group.getGroupName());
}
criteria.setExcludeSourceList(excludeSources);
}
}
Query query = QueryHelp.getQuery(criteria);
//查询所有出库中或关闭的
query.addCriteria(Criteria.where("status").in(new Integer[]{LITEORDER_STATUS.EXECUTING, LITEORDER_STATUS.CLOSED}));
query.addCriteria(Criteria.where("sheetEnd").ne(true));
PageData<LiteOrder> orderList = liteOrderManager.findByPage(query, pageable);
PageData<OrderDto> resultList = orderMapper.toDto(orderList);
return resultList;
}
@ApiOperation("扫码料盘获取位置信息")
@PostMapping(value = "/getOrderRIPos")
@PreAuthorize("@el.check('workOrder')")
public OrderRIPostDto getOrderRIPos(@RequestBody String barcode) {
// String code = mapValues.get("barcode").toString();
Barcode barcodeInfo = codeResolve.resolveOneValideBarcode(barcode);
if (barcodeInfo == null) {
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"条码"});
}
DataLog dataLog=dataLogManager.findLastOutTask(barcodeInfo.getBarcode());
if (dataLog == null) {
throw new ValidateException("smfcore.orderSheet.barcode", "未找到料盘{0}的工单信息",new String[]{barcodeInfo.getBarcode()} );
}
//TODO 判断任务是否已结束,未结束不能绑定位置
LiteOrder liteOrder= liteOrderManager.findByOrderNo(dataLog.getSourceName());
if(liteOrder==null){
throw new ValidateException("smfcore.orderSheet.barcode", "未找到料盘{0}的工单信息",new String[]{barcodeInfo.getBarcode()} );
}
if(liteOrder.getBoxNum()<=0){
throw new ValidateException("smfcore.orderSheet.noBox", "工单{0}还未绑定箱子",new String[]{liteOrder.getOrderNo()} );
}
int type=3;
if(dataLog.isNeedSplitting()){
type=2;
}else if(dataLog.isFirstReel()){
type=1;
}
boolean isSave=false;
if(liteOrder.getCurrBoxNum()==null){
liteOrder.setCurrBoxNum(1);
isSave=true;
}else if(liteOrder.getCurrBoxNum()<liteOrder.getBoxNum()){
liteOrder.setCurrBoxNum(liteOrder.getCurrBoxNum()+1);
isSave=true;
}
if(isSave){
log.info("工单合单:料盘条码["+barcodeInfo.getBarcode()+"],工单号["+liteOrder.getOrderNo()+"],箱子数+1,当前箱子数:"+liteOrder.getCurrBoxNum()+"/"+liteOrder.getBoxNum());
liteOrderManager.save(liteOrder);
liteOrderCache.addOrderToMap(liteOrder);
}
OrderRIPostDto dto=new OrderRIPostDto(barcodeInfo.getBarcode(),liteOrder.getOrderNo(),type,liteOrder.getBoxNum(),liteOrder.getCurrBoxNum(),liteOrder.getPosition(type));
return dto;
}
@ApiOperation("绑定位置")
@PostMapping(value = "/bindPosition")
@PreAuthorize("@el.check('workOrder')")
public ResultBean bindPosition(@RequestBody Map<String, Object> mapValues) {
String orderNo = mapValues.get("orderNo").toString();
int type =Integer.parseInt(mapValues.get("type").toString()) ;
String position=mapValues.get("position").toString();
LiteOrder liteOrder= liteOrderManager.findByOrderNo(orderNo);
if(liteOrder==null){
throw new ValidateException("smfcore.orderSheet.barcode", "未找到工单{0}",new String[]{orderNo} );
}
if(liteOrder.getBoxNum()<=0){
throw new ValidateException("smfcore.orderSheet.noBox", "工单{0}还未绑定箱子",new String[]{liteOrder.getOrderNo()} );
}
String pos=liteOrder.getPosition(type);
if(ObjectUtil.isNotEmpty(pos)){
throw new ValidateException("smfcore.orderSheet.hasPos", "工单{0}已有{1}位置{2}",new String[]{orderNo,liteOrder.getPosition(type),pos} );
}
if(liteOrder.getPosInfos()!=null){
for (OrderPosInfo posInfo :
liteOrder.getPosInfos()) {
if (posInfo.getPosition().equals(position)) {
throw new ValidateException("smfcore.orderSheet.hasPos", "工单{0}已有{1}位置{2}",new String[]{orderNo,liteOrder.getPosition(posInfo.getType()),position} );
}
}
}
liteOrder.addPos(type,position);
log.info("工单合单:工单号["+liteOrder.getOrderNo()+"]绑定位置["+type+"]["+position+"]");
liteOrderManager.save(liteOrder);
liteOrderCache.addOrderToMap(liteOrder);
return ResultBean.newOkResult("smfcore.orderSheet.bindPosition.ok","绑定成功",position);
}
@ApiOperation("完成合单")
@PostMapping(value = "/endOrderSheet")
@PreAuthorize("@el.check('workOrder')")
public ResultBean endOrderSheet(@RequestBody Map<String, Object> mapValues) {
String orderNo = mapValues.get("orderNo").toString();
LiteOrder liteOrder= liteOrderManager.findByOrderNo(orderNo);
if(liteOrder==null){
throw new ValidateException("smfcore.orderSheet.barcode", "未找到工单{0}",new String[]{orderNo} );
}
if(liteOrder.getBoxNum()<=0){
throw new ValidateException("smfcore.orderSheet.noBox", "工单{0}还未绑定箱子",new String[]{liteOrder.getOrderNo()} );
}
if(liteOrder.getCurrBoxNum()<liteOrder.getBoxNum()){
throw new ValidateException("smfcore.orderSheet.endOrderSheet.error", "工单{0}合单进度未完成",new String[]{orderNo} );
}
log.info("工单合单:工单号["+liteOrder.getOrderNo()+"]完成合单");
liteOrder.setSheetEnd(true);
liteOrderManager.save(liteOrder);
liteOrderCache.addOrderToMap(liteOrder);
return ResultBean.newOkResult("ok");
}
}
......@@ -99,7 +99,17 @@ public class OrderDto implements Serializable {
@ApiModelProperty("是否是当前操作工单")
private boolean inOperate=false;
@ApiModelProperty(value = "总箱子数")
private Integer boxNum;
@ApiModelProperty(value = "当前箱子数")
private Integer currBoxNum;
@ApiModelProperty(value = "工单是否完成合单")
private Boolean sheetEnd;
@ApiModelProperty(value = "工单是否欠料发料")
private Boolean shortageOut;
// @ApiModelProperty("建议出仓时间")
// private Date sdate=new Date();
......
package com.neotel.smfcore.core.order.rest.bean.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 工单合单页面,扫码获取料盘的工单信息及位置
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class OrderRIPostDto {
@ApiModelProperty(value = "料盘条码")
private String barcode;
@ApiModelProperty(value = "工单号")
private String orderNo;
@ApiModelProperty(value = "物料类型:1=首料,2=截料,3=备料,4=欠料")
private int riType=3;
@ApiModelProperty(value = "总箱子数")
private Integer boxNum;
@ApiModelProperty(value = "当前箱子数")
private Integer currBoxNum;
@ApiModelProperty(value = "位置")
private String position;
}
package com.neotel.smfcore.core.order.rest.bean.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class OrderSheetDto {
@ApiModelProperty(value = "ID")
private String id;
@ApiModelProperty("工单号")
private String orderNo;
@ApiModelProperty(value = "总箱子数")
private Integer boxNum;
@ApiModelProperty(value = "当前箱子数")
private Integer currBoxNum;
}
......@@ -2,6 +2,8 @@ package com.neotel.smfcore.core.order.service.po;
import com.neotel.smfcore.common.base.BasePo;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.core.order.bean.OrderBoxInfo;
import com.neotel.smfcore.core.order.bean.OrderPosInfo;
import com.neotel.smfcore.core.order.enums.LITEORDER_STATUS;
import com.neotel.smfcore.hikvision.bean.HikOrderInfo;
import lombok.Data;
......@@ -142,6 +144,41 @@ public class LiteOrder extends BasePo implements Serializable {
private List<LiteOrderItem> orderItems;
/**
* 绑定的箱子信息
*/
private List<OrderBoxInfo> boxInfos;
/**
* 工单位置信息
*/
private List<OrderPosInfo> posInfos;
/**
* 当前箱子数
*/
private Integer currBoxNum;
/**
* 工单是否完成合单
*/
private Boolean sheetEnd;
/**
* 工单是否欠料发料
*/
private Boolean shortageOut;
/**
* 工单是否齐套(欠料出库才用)
*/
private Boolean complete;
public Integer getBoxNum(){
if(boxInfos!=null){
return boxInfos.size();
}
return 0;
}
public void setClosed(boolean value){
this.closed=value;
......@@ -249,4 +286,57 @@ public class LiteOrder extends BasePo implements Serializable {
}
return null;
}
public boolean hasBox(String boxName){
if(boxInfos!=null){
for (OrderBoxInfo box :
boxInfos) {
if(box.getBoxName().equals(boxName)){
return true;
}
}
}
return false;
}
public void addBox(OrderBoxInfo boxInfo){
if(boxInfos==null){
boxInfos=new ArrayList<>();
}
boxInfos.add(boxInfo);
}
public String getPosition(int type) {
if(posInfos==null){
return "";
}
for (OrderPosInfo obj :
posInfos ) {
if(obj.getType()==type){
return obj.getPosition();
}
}
return "";
}
public String getRITypeStr(int type){
// 1=首料,2=截料,3=备料,4=欠料
if(type==1){
return "首料";
}else if(type==2){
return "截料";
}else if(type==3){
return "备料";
}else if(type==4){
return "欠料";
}
return "";
}
public void addPos(int type, String position) {
if(posInfos==null){
posInfos=new ArrayList<>();
}
posInfos.add(new OrderPosInfo(position,type));
}
}
......@@ -594,7 +594,7 @@ public class StoragePosManagerImpl implements IStoragePosManager {
.and("id").nin(excludePosIds)
.and("enabled").is(true)//可用
.and("barcode.lockId").is(null)//没有被锁定的仓位;
.and("barcode.lockMsl").is(false);//湿敏超期物料所在仓位锁定, 不允许备料
.and("barcode.lockMsl").ne(true);//湿敏超期物料所在仓位锁定, 不允许备料
if (storageIdList != null) {
c = c.and("storageId").in(storageIdList);
}
......
......@@ -7,4 +7,6 @@ import java.util.List;
public interface IDataLogManager extends IBaseManager<DataLog> {
List<DataLog> findUnFinishedTasks();
DataLog findLastOutTask(String barcode);
}
......@@ -8,6 +8,7 @@ import com.neotel.smfcore.core.system.service.manager.IDataLogManager;
import com.neotel.smfcore.core.system.service.po.DataLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
......@@ -63,4 +64,14 @@ public class DataLogManagerImpl implements IDataLogManager {
}
return unFinishedTasks;
}
@Override
public DataLog findLastOutTask(String barcode) {
Query query = new Query(Criteria.where("barcode").is(barcode));
query.addCriteria(Criteria.where("outType").is(10));
Sort sort = Sort.by(Sort.Direction.DESC, "createDate");
query.with(sort);
DataLog dataLog = dataLogDao.findOne(query);
return dataLog;
}
}
......@@ -55,3 +55,17 @@ hik:
addr_9_updateRepOrderApi: http://192.168.0.0.1/mes/updateRepOrderApi
addr_10_reservedOrderApi: http://192.168.0.0.1/mes/reservedOrderApi
addr_11_orderEndApi: http://192.168.0.0.1/mes/orderEndApi
20220523更新:
1.唯一码验证bug修改(湿敏物料入库问题)。
2.元器件增加物料间距,uid查找增加间距区间。
3.接口异常默认根据更新时间倒序。
4.出库单出库完成显示出库中问题修改。
5.物料日志增加详细出入库类型查询。
20220526:周四需要更新:
1.元器件字段修改:截料设置盘数,安全库存盘数,补充盘数限制。
2.入库单增加凭证号,物料日志页面分来源一,来源二。
3.UID出库,增加物料编号,批次,供应商 查询。
4.齐套缺料改为:分开计算每个工单缺少多少盘, 然后最后把总盘数加起来
\ No newline at end of file
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!