| | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.baomidou.mybatisplus.mapper.EntityWrapper; |
| | | import com.core.annotations.ManagerAuth; |
| | | import com.core.common.BaseRes; |
| | | import com.core.common.Cools; |
| | | import com.core.common.R; |
| | | import com.core.exception.CoolException; |
| | | import com.zy.asrs.entity.*; |
| | | import com.zy.asrs.service.*; |
| | | import com.zy.common.model.LocDto; |
| | |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.*; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Optional; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | |
| | | private BasDevpService basDevpService; |
| | | @Autowired |
| | | private MatService matService; |
| | | @Autowired |
| | | private AgvLocMastService agvLocMastService; |
| | | @Autowired |
| | | private AgvBasDevpService agvBasDevpService; |
| | | @Autowired |
| | | private AgvWorkService agvWorkService; |
| | | |
| | | @Autowired |
| | | private AgvLocDetlService agvLocDetlService; |
| | | |
| | | @PostMapping("/out/pakout/orderDetlIds/auth") |
| | | @ManagerAuth |
| | |
| | | return R.ok().add(orderDetlService.selectByOrderId(orderId).stream().map(OrderDetl::getId).distinct().collect(Collectors.toList())); |
| | | } |
| | | |
| | | //出库 |
| | | @PostMapping("/out/pakout/preview/auth") |
| | | @ManagerAuth |
| | | public R pakoutPreview(@RequestBody List<Long> ids) { |
| | | |
| | | List<OrderDetl> orderDetlList = orderDetlService.selectBatchIds(ids); |
| | | //返回给前端的库位以及站点信息 |
| | | List<LocDto> locDtoList = new ArrayList<>(); |
| | | |
| | | for (OrderDetl orderDetl : orderDetlList) { |
| | | double issued = Optional.of(orderDetl.getAnfme() - orderDetl.getQty()).orElse(0.0D); |
| | | if (issued <= 0.0D) { continue; } |
| | | |
| | | //先找AGV的库存,如果返回的issued大于0,则去四项库找 |
| | | issued = agvLocDetlService.queryStockAndSetLocDto(orderDetl.getMatnr(),orderDetl.getBatch(),orderDetl.getOrderNo(),locDtoList,issued); |
| | | |
| | | //从四项库的库存里面找, |
| | | issued = locDetlService.queryStockAndSetLocDto(orderDetl.getMatnr(),orderDetl.getBatch(),orderDetl.getOrderNo(),locDtoList,issued); |
| | | |
| | | if (issued > 0) { |
| | | LocDto locDto = new LocDto(null, orderDetl.getMatnr(), orderDetl.getMaktx(), orderDetl.getBatch(), orderDetl.getOrderNo(), issued); |
| | | locDto.setLack(Boolean.TRUE); |
| | | locDtoList.add(locDto); |
| | | } |
| | | } |
| | | return R.ok().add(locDtoList); |
| | | |
| | | /* |
| | | if (Cools.isEmpty(ids)) { |
| | | return R.parse(BaseRes.PARAM); |
| | | } |
| | |
| | | locDtos.add(locDto); |
| | | } |
| | | } |
| | | return R.ok().add(locDtos); |
| | | return R.ok().add(locDtos); */ |
| | | } |
| | | |
| | | @PostMapping("/out/pakout/auth") |
| | | @ManagerAuth(memo = "订单出库") |
| | | @Transactional |
| | | public synchronized R pakout(@RequestBody List<LocDto> locDtos) throws InterruptedException { |
| | | |
| | | //判断是否可以生成出库工作档 |
| | | boolean lack = true; |
| | | for (LocDto locDto : locDtos) { |
| | | //如果AGV出库站为空 和 四项库出库站为空 并且 有库存的情况下 则返回 |
| | | if (Cools.isEmpty(locDto.getStaNo()) && Cools.isEmpty(locDto.getAgvStaNo()) &&!locDto.isLack()) { |
| | | return R.error(locDto.getLocNo()+"库位请选择出库站"); |
| | | } |
| | | } |
| | | //如果所有库都没有库存,则返回 |
| | | for (LocDto locDto : locDtos) { |
| | | if (!locDto.isLack()) { |
| | | lack = false; |
| | | break; |
| | | } |
| | | } |
| | | if (lack) { |
| | | return R.error("库存不足"); |
| | | } |
| | | Thread.sleep(500L); |
| | | |
| | | // 订单预校验 ===>> 1.订单状态; 2.订单带出数量 |
| | | List<OrderDto> orderDtos = orderPreVerification(locDtos); |
| | | |
| | | List<TaskDto> taskDtos = new ArrayList<>(); |
| | | List<TaskDto> agvTaskDtos = new ArrayList<>(); |
| | | generateTaskDto(locDtos,taskDtos,agvTaskDtos); |
| | | |
| | | //生成AGV出库任务 |
| | | agvWorkService.stockOutWrkMast(agvTaskDtos, getUserId()); |
| | | |
| | | // 生成出库任务 |
| | | List<String> excludeLocNos = taskDtos.stream().map(TaskDto::getLocNo).distinct().collect(Collectors.toList()); |
| | | for (TaskDto taskDto : taskDtos) { |
| | | BasDevp staNo = basDevpService.checkSiteStatus(taskDto.getStaNo()); |
| | | workService.stockOut(staNo, taskDto, getUserId()); |
| | | locMastService.breakUp(taskDto.getLocNo(), excludeLocNos); |
| | | } |
| | | return R.ok(); |
| | | |
| | | /* |
| | | if (Cools.isEmpty(locDtos)) { |
| | | return R.parse(BaseRes.PARAM); |
| | | } |
| | |
| | | workService.stockOut(staNo, taskDto, getUserId()); |
| | | locMastService.breakUp(taskDto.getLocNo(), excludeLocNos); |
| | | } |
| | | return R.ok(); |
| | | return R.ok();*/ |
| | | } |
| | | |
| | | |
| | |
| | | @PostMapping("/out/pakout/preview/merge/auth") |
| | | @ManagerAuth |
| | | public R pakoutPreviewMerge(@RequestBody List<OrderMergeVo> list) { |
| | | |
| | | //返回给前端的库位以及站点信息 |
| | | List<LocDto> locDtoList = new ArrayList<>(); |
| | | |
| | | for (OrderMergeVo vo : list) { |
| | | double issued = Optional.of(vo.getAnfme()).orElse(0.0D); |
| | | if (issued <= 0.0D) { |
| | | continue; |
| | | } |
| | | //先找AGV的库存,如果返回的issued大于0,则去四项库找 |
| | | issued = agvLocDetlService.queryStockAndSetLocDto(vo.getMatnr(),vo.getBatch(),null,locDtoList,issued); |
| | | //从四项库的库存里面找, |
| | | issued = locDetlService.queryStockAndSetLocDto(vo.getMatnr(),vo.getBatch(),null,locDtoList,issued); |
| | | |
| | | if (issued > 0) { |
| | | LocDto locDto = new LocDto(null, vo.getMatnr(), vo.getMaktx(), vo.getBatch(), null, issued); |
| | | locDto.setLack(Boolean.TRUE); |
| | | locDtoList.add(locDto); |
| | | } |
| | | |
| | | } |
| | | |
| | | return R.ok().add(locDtoList); |
| | | |
| | | /* |
| | | if (Cools.isEmpty(list)) { |
| | | return R.parse(BaseRes.PARAM); |
| | | } |
| | |
| | | assert mat != null; |
| | | locDto.setSpecs(mat.getSpecs()); |
| | | } |
| | | return R.ok().add(locDtos); |
| | | return R.ok().add(locDtos);*/ |
| | | } |
| | | |
| | | |
| | | /* |
| | | 生成出库任务dto |
| | | */ |
| | | private void generateTaskDto(List<LocDto> locDtos, List<TaskDto> taskDtos, List<TaskDto> agvTaskDtos){ |
| | | // 根据 (库位 & 出库站) 分组; 理想状态:一组为一次出库任务 |
| | | for (LocDto locDto : locDtos) { |
| | | if (locDto.isLack()) { continue; } |
| | | //AGV库 |
| | | if(!Cools.isEmpty(locDto.getAgvStaNos())){ |
| | | generateTaskDtoForAgv(locDto,agvTaskDtos); |
| | | |
| | | //四项库 |
| | | }else{ |
| | | generateTaskDtoForBase(locDto,taskDtos); |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | /* |
| | | 生成AGV的任务dto |
| | | */ |
| | | private void generateTaskDtoForAgv(LocDto locDto, List<TaskDto> agvTaskDtos){ |
| | | // 防止前端页面提取库位信息后,在其他地方对该库位生成了出库任务(库位状态非F状态) |
| | | AgvLocMast agvLocMast = agvLocMastService.selectById(locDto.getLocNo()); |
| | | if(!Cools.isEmpty(agvLocMast) && !agvLocMast.getLocSts().equals("F")){ |
| | | throw new CoolException("库位号非在库状态,请重新选择出库库位===>>" + locDto.getLocNo()); |
| | | } |
| | | AgvBasDevp agvBasDevp = agvBasDevpService.selectOne(new EntityWrapper<AgvBasDevp>() |
| | | .eq("station_code", locDto.getAgvStaNo()) |
| | | .eq("loc_sts", "O")); |
| | | if(Cools.isEmpty(agvBasDevp)){ |
| | | //TODO 假如出库站点不足,记录未出库的库位; |
| | | return; |
| | | } |
| | | TaskDto taskDto = new TaskDto(locDto.getLocNo(), agvBasDevp.getDevNo(), locDto); |
| | | //TODO 暂不考虑库位混载状态(后续看情况是否需要判断) |
| | | agvTaskDtos.add(taskDto); |
| | | |
| | | } |
| | | |
| | | /* |
| | | 生成四项库的任务dto |
| | | */ |
| | | private void generateTaskDtoForBase(LocDto locDto, List<TaskDto> taskDtos){ |
| | | // 防止前端页面提取库位信息后,在其他地方对该库位生成了出库任务(库位状态非F状态) |
| | | LocMast locMast = locMastService.selectById(locDto.getLocNo()); |
| | | if(!Cools.isEmpty(locMast) && !locMast.getLocSts().equals("F")){ |
| | | throw new CoolException("库位号非在库状态,请重新选择出库库位===>>" + locDto.getLocNo()); |
| | | } |
| | | |
| | | TaskDto taskDto = new TaskDto(locDto.getLocNo(), locDto.getStaNo(), locDto); |
| | | //如果库位存在混载 |
| | | if (TaskDto.has(taskDtos, taskDto)) { |
| | | TaskDto dto = TaskDto.find(taskDtos, taskDto); |
| | | assert dto != null; |
| | | dto.getLocDtos().addAll(taskDto.getLocDtos()); |
| | | } else { |
| | | taskDtos.add(taskDto); |
| | | } |
| | | } |
| | | |
| | | /* |
| | | 订单预校验 ===>> 1.订单状态; 2.订单带出数量 |
| | | */ |
| | | private List<OrderDto> orderPreVerification(List<LocDto> locDtos){ |
| | | List<OrderDto> orderDtos = new ArrayList<>(); |
| | | for (LocDto locDto : locDtos) { |
| | | if (!isJSON(locDto.getOrderNo())) { |
| | | //if (!Cools.isEmpty(locDto.getOrderNo())) { |
| | | if (Cools.isEmpty(locDto.getOrderNo())) { continue; } |
| | | OrderDto orderDto = new OrderDto(locDto.getOrderNo(), locDto.getMatnr(), locDto.getBatch(), locDto.getAnfme()); |
| | | if (OrderDto.has(orderDtos, orderDto)) { |
| | | OrderDto dto = OrderDto.find(orderDtos, orderDto); |
| | | assert dto != null; |
| | | dto.setAnfme(dto.getAnfme() + orderDto.getAnfme()); |
| | | } else { |
| | | orderDtos.add(orderDto); |
| | | } |
| | | } else { |
| | | // 订单合并出库 |
| | | List<OrderDto> orderDtoList = JSON.parseArray(locDto.getOrderNo(), OrderDto.class); |
| | | for (OrderDto one : orderDtoList) { |
| | | OrderDto orderDto = new OrderDto(one.getOrderNo(), locDto.getMatnr(), locDto.getBatch(), one.getAnfme()); |
| | | if (OrderDto.has(orderDtos, orderDto)) { |
| | | OrderDto dto = OrderDto.find(orderDtos, orderDto); |
| | | assert dto != null; |
| | | dto.setAnfme(dto.getAnfme() + orderDto.getAnfme()); |
| | | } else { |
| | | orderDtos.add(orderDto); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | for (OrderDto orderDto : orderDtos) { |
| | | Order order = orderService.selectByNo(orderDto.getOrderNo()); |
| | | if (order.getSettle() > 2) { |
| | | throw new CoolException(orderDto.getOrderNo() + "订单已失效,请及时刷新页面"); |
| | | //return R.error(orderDto.getOrderNo() + "订单已失效,请及时刷新页面"); |
| | | } |
| | | } |
| | | return orderDtos; |
| | | } |
| | | } |
| | |
| | | @ExcelProperty("物料号") |
| | | private String matnr; |
| | | |
| | | @ApiModelProperty(value= "物料号") |
| | | @ExcelProperty("物料号") |
| | | @ApiModelProperty(value= "物料名称") |
| | | @ExcelProperty("物料名称") |
| | | private String maktx; |
| | | |
| | | @ApiModelProperty(value= "序列码") |
| | |
| | | |
| | | import com.baomidou.mybatisplus.service.IService; |
| | | import com.zy.asrs.entity.AgvLocDetl; |
| | | import com.zy.common.model.LocDto; |
| | | |
| | | import java.util.List; |
| | | |
| | | public interface AgvLocDetlService extends IService<AgvLocDetl> { |
| | | |
| | | public void addLocDetlInfo(String locNo, int taskCode); |
| | | |
| | | public double queryStockAndSetLocDto(String matnr, String batch, String orderNo, List<LocDto> locDtoList, double issued); |
| | | |
| | | } |
| | |
| | | |
| | | import com.zy.asrs.entity.AgvBasDevp; |
| | | import com.zy.common.model.StartupDto; |
| | | import com.zy.common.model.TaskDto; |
| | | |
| | | import java.util.List; |
| | | |
| | | public interface AgvWorkService { |
| | | |
| | | /** |
| | | * 通知档手动生成任务 |
| | | /* |
| | | 通知档手动生成任务 |
| | | */ |
| | | StartupDto createWaitPainWrkMastStart(List<AgvBasDevp> agvBasDevpList, Long userId); |
| | | |
| | | /* |
| | | 生成出库任务 |
| | | */ |
| | | void stockOutWrkMast(List<TaskDto> agvTaskDtos, Long userId); |
| | | |
| | | |
| | | } |
| | |
| | | import com.baomidou.mybatisplus.service.IService; |
| | | import com.zy.asrs.entity.LocDetl; |
| | | import com.zy.asrs.entity.result.StockVo; |
| | | import com.zy.common.model.LocDto; |
| | | |
| | | import java.util.List; |
| | | import java.util.Set; |
| | |
| | | |
| | | List<LocDetl> queryStock(String matnr, String batch, String orderNo, Set<String> locNos); |
| | | |
| | | double queryStockAndSetLocDto(String matnr, String batch, String orderNo, List<LocDto> locDtoList, double issued); |
| | | |
| | | Double queryStockAnfme(String matnr, String batch); |
| | | |
| | | List<StockVo> queryStockTotal(); |
| | |
| | | package com.zy.asrs.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.mapper.EntityWrapper; |
| | | import com.baomidou.mybatisplus.mapper.Wrapper; |
| | | import com.baomidou.mybatisplus.service.impl.ServiceImpl; |
| | | import com.core.common.Cools; |
| | | import com.zy.asrs.entity.AgvLocDetl; |
| | | import com.zy.asrs.entity.AgvLocMast; |
| | | import com.zy.asrs.entity.AgvWrkDetl; |
| | | import com.zy.asrs.mapper.AgvLocDetlMapper; |
| | | import com.zy.asrs.service.AgvBasDevpService; |
| | | import com.zy.asrs.service.AgvLocDetlService; |
| | | import com.zy.asrs.service.AgvLocMastService; |
| | | import com.zy.asrs.service.AgvWrkDetlService; |
| | | import com.zy.common.model.LocDto; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | | |
| | |
| | | |
| | | @Autowired |
| | | AgvWrkDetlService agvWrkDetlService; |
| | | @Autowired |
| | | AgvBasDevpService agvBasDevpService; |
| | | @Autowired |
| | | AgvLocMastService agvLocMastService; |
| | | |
| | | public void addLocDetlInfo(String locNo, int taskCode) { |
| | | List<AgvWrkDetl> agvWrkDetls = agvWrkDetlService.selectList(new EntityWrapper<AgvWrkDetl>().eq("wrk_no", taskCode)); |
| | |
| | | }).collect(Collectors.toList()); |
| | | |
| | | } |
| | | |
| | | public double queryStockAndSetLocDto(String matnr, String batch, String orderNo, List<LocDto> locDtoList, double issued) { |
| | | //根据物料号和批次找到对应的库存,并且按照修改时间排序 |
| | | Wrapper<AgvLocDetl> wrapper = new EntityWrapper<AgvLocDetl>().eq("matnr", matnr).orderBy("modi_time"); |
| | | if(Cools.isEmpty(batch)){ |
| | | wrapper.isNull("batch"); |
| | | }else { |
| | | wrapper.eq("batch",batch); |
| | | } |
| | | List<AgvLocDetl> agvLocDetls = this.selectList(wrapper); |
| | | |
| | | for (AgvLocDetl agvLocDetl: agvLocDetls) { |
| | | //判断当前库位货物是否F在库 |
| | | AgvLocMast agvLocMast = agvLocMastService.selectById(agvLocDetl.getLocNo()); |
| | | if(!"F".equals(agvLocMast.getLocSts())){ |
| | | continue; |
| | | } |
| | | //如果订单剩余出库量大于0 |
| | | if(issued > 0) { |
| | | //当前库位的库存量 |
| | | double anfme = agvLocDetl.getAnfme(); |
| | | //int ioType = anfme > issued ? 101 : 103; |
| | | anfme = anfme > issued ? issued : anfme; |
| | | LocDto locDto = new LocDto(agvLocDetl.getLocNo(), agvLocDetl.getMatnr(), agvLocDetl.getMaktx(), agvLocDetl.getBatch(), orderNo, anfme); |
| | | |
| | | //当前库位所处楼层 |
| | | int floor = Integer.parseInt(agvLocDetl.getLocNo().split("@")[1]); |
| | | locDto.setAgvStaNos(queryAgvStaNosByFloor(floor)); |
| | | locDtoList.add(locDto); |
| | | |
| | | issued -= anfme; |
| | | } |
| | | } |
| | | |
| | | return issued; |
| | | |
| | | } |
| | | |
| | | private List<String> queryAgvStaNosByFloor(int floor){ |
| | | List<String> agvStaNos = new ArrayList<>(); |
| | | if(floor == 1){ |
| | | agvStaNos.add("CS-101"); |
| | | agvStaNos.add("CS-102"); |
| | | }else if(floor ==3){ |
| | | agvStaNos.add("CS-305"); |
| | | agvStaNos.add("CS-306"); |
| | | agvStaNos.add("CS-307"); |
| | | } |
| | | |
| | | return agvStaNos; |
| | | } |
| | | } |
| | |
| | | package com.zy.asrs.service.impl; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.baomidou.mybatisplus.mapper.EntityWrapper; |
| | | import com.core.common.Cools; |
| | | import com.core.exception.CoolException; |
| | | import com.zy.asrs.entity.*; |
| | | import com.zy.asrs.service.*; |
| | | import com.zy.common.model.LocDto; |
| | | import com.zy.common.model.OrderDto; |
| | | import com.zy.common.model.StartupDto; |
| | | import com.zy.common.model.TaskDto; |
| | | import com.zy.common.model.enums.WorkNoType; |
| | | import com.zy.common.service.AgvCommonService; |
| | | import com.zy.common.web.BaseController; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | |
| | | @Autowired |
| | | private AgvLocMastService agvLockMastService; |
| | | @Autowired |
| | | private AgvLocDetlService agvLocDetlService; |
| | | @Autowired |
| | | private AgvCommonService agvCommonService; |
| | | @Autowired |
| | | private AgvWrkMastService agvWrkMastService; |
| | |
| | | private AgvWrkDetlService agvWrkDetlService; |
| | | @Autowired |
| | | private MatService matService; |
| | | @Autowired |
| | | private OrderService orderService; |
| | | @Autowired |
| | | private OrderDetlService orderDetlService; |
| | | |
| | | @Override |
| | | |
| | | /* |
| | | 入库 |
| | | */ |
| | | @Transactional |
| | | public StartupDto createWaitPainWrkMastStart(List<AgvBasDevp> agvBasDevpList, Long userId) { |
| | | |
| | | Date now = new Date(); |
| | |
| | | //检索库位,选择合适的库位 |
| | | AgvLocMast agvLocMast = agvCommonService.getLocNo(agvWaitPakinList, agvBasDevp.getFloor()); |
| | | //生成工作档 |
| | | AgvWrkMast wrkMast = createWrkMast(agvBasDevp, agvLocMast, now, userId); |
| | | //AgvWrkMast wrkMast = createWrkMast(agvBasDevp, agvLocMast, now, userId); |
| | | AgvWrkMast wrkMast = createWrkMast(1,201L,agvBasDevp.getDevNo(),agvLocMast.getLocNo(),agvBasDevp.getBarcode(),now,userId); |
| | | //生成工作档明细 |
| | | createWrkDetlReWrite(agvWaitPakinList,wrkMast,userId); |
| | | //createWrkDetlReWrite(agvWaitPakinList,wrkMast,userId); |
| | | agvWaitPakinList.forEach(wp -> { |
| | | createWrkDetlReWrite(wp.getMatnr(),wrkMast.getWrkNo(),wp.getOrderNo(),wp.getBatch(),wp.getAnfme(),wp.getZpallet(),now,userId); |
| | | }); |
| | | //更新源站点信息 |
| | | updateAgvBasDevp(agvBasDevp); |
| | | updateAgvBasDevp(agvBasDevp,"R"); |
| | | //更新目标库位状态 |
| | | updateAgvLocMast(agvLocMast); |
| | | updateAgvLocMast(agvLocMast,"S"); |
| | | |
| | | }); |
| | | |
| | | //TODO |
| | | return null; |
| | | } |
| | | |
| | | /* |
| | | 订单出库 |
| | | */ |
| | | @Transactional |
| | | public void stockOutWrkMast(List<TaskDto> agvTaskDtos, Long userId) { |
| | | Date now = new Date(); |
| | | |
| | | agvTaskDtos.forEach(taskDto -> { |
| | | |
| | | AgvLocMast agvLocMast = agvLockMastService.selectById(taskDto.getLocNo()); |
| | | |
| | | //工作档所需参数 |
| | | double anfme = taskDto.getLocDtos().get(0).getAnfme(); |
| | | long wrkSts = 21L; |
| | | String sourceLocNo = taskDto.getLocNo(); |
| | | String targetLocNo = taskDto.getAgvStaNo(); |
| | | String barcode = agvLocMast.getBarcode(); |
| | | //明细档所需参数 |
| | | String mantr = taskDto.getLocDtos().get(0).getMatnr(); |
| | | String orderNo = taskDto.getLocDtos().get(0).getOrderNo(); |
| | | String batch = taskDto.getLocDtos().get(0).getBatch(); |
| | | |
| | | //判断是否全板出库 |
| | | int ioType = isPakOut(sourceLocNo,anfme) ? 101 : 103; |
| | | //生成工作档 |
| | | AgvWrkMast wrkMast = createWrkMast(ioType,wrkSts,sourceLocNo,targetLocNo,barcode,now,userId); |
| | | //生成工作档明细 |
| | | createWrkDetlReWrite(mantr,wrkMast.getWrkNo(),orderNo,batch,anfme,barcode,now,userId); |
| | | //修改订单信息 |
| | | modifyOrderDetl(taskDto.getLocDtos().get(0), userId); |
| | | //更新源站点信息 |
| | | updateAgvLocMast(agvLockMastService.selectById(sourceLocNo),"R"); |
| | | //更新目标站点状态 |
| | | updateAgvBasDevp(agvBasDevpService.selectById(targetLocNo),"S"); |
| | | |
| | | }); |
| | | } |
| | | |
| | | /* |
| | | 更新目标库位信息 |
| | | */ |
| | | private void updateAgvLocMast(AgvLocMast locMast){ |
| | | locMast.setLocSts("S"); |
| | | private void updateAgvLocMast(AgvLocMast locMast, String locSts){ |
| | | locMast.setLocSts(locSts); |
| | | agvLockMastService.updateById(locMast); |
| | | } |
| | | |
| | | /* |
| | | 更新源站点信息 |
| | | */ |
| | | private void updateAgvBasDevp(AgvBasDevp agvBasDevp){ |
| | | agvBasDevp.setLocSts("R"); |
| | | private void updateAgvBasDevp(AgvBasDevp agvBasDevp, String locSts){ |
| | | agvBasDevp.setLocSts(locSts); |
| | | agvBasDevpService.updateById(agvBasDevp); |
| | | } |
| | | |
| | | /* |
| | | 生成工作档明细 |
| | | */ |
| | | /* private void createWrkDetl(List<AgvWaitPakin> agvWaitPakinList, AgvWrkMast wrkMast, Long userId){ |
| | | List<DetlDto> detlDtos = new ArrayList<>(); |
| | | agvWaitPakinList.forEach(agvWaitPakin -> { |
| | | DetlDto detlDto = new DetlDto(agvWaitPakin.getMatnr(), agvWaitPakin.getBatch(), agvWaitPakin.getAnfme()); |
| | | if (DetlDto.has(detlDtos, detlDto)) { |
| | | DetlDto detlDto1 = DetlDto.find(detlDtos, detlDto.getMatnr(), detlDto.getBatch()); |
| | | assert detlDto1 != null; |
| | | detlDto1.setAnfme(detlDto1.getAnfme() + detlDto.getAnfme()); |
| | | } else { |
| | | detlDtos.add(detlDto); |
| | | } |
| | | }); |
| | | agvWrkDetlService.createWorkDetail(wrkMast.getWrkNo(), detlDtos, wrkMast.getBarcode(), userId); |
| | | }*/ |
| | | private void createWrkDetlReWrite(String matnr, int wrkNo, String orderNo,String batch, double anfme, String zpallet, Date now, Long userId){ |
| | | Mat mat = matService.selectByMatnr(matnr); |
| | | if (Cools.isEmpty(mat)) { |
| | | throw new CoolException(matnr + "商品维护失败"); |
| | | } |
| | | AgvWrkDetl wrkDetl = new AgvWrkDetl(); |
| | | wrkDetl.sync(mat); |
| | | wrkDetl.setWrkNo(wrkNo); |
| | | wrkDetl.setOrderNo(orderNo); |
| | | wrkDetl.setIoTime(now); |
| | | wrkDetl.setBatch(batch); |
| | | wrkDetl.setAnfme(anfme); // 数量 |
| | | wrkDetl.setZpallet(zpallet); // 托盘条码 |
| | | wrkDetl.setAppeUser(userId); |
| | | wrkDetl.setAppeTime(now); |
| | | wrkDetl.setModiUser(userId); |
| | | wrkDetl.setModiTime(now); |
| | | if (!agvWrkDetlService.insert(wrkDetl)) { |
| | | throw new CoolException("保存工作明细失败"); |
| | | } |
| | | } |
| | | |
| | | /* |
| | | 生成工作档明细 |
| | | */ |
| | | @Deprecated |
| | | private void createWrkDetlReWrite(List<AgvWaitPakin> agvWaitPakinList, AgvWrkMast wrkMast, Long userId){ |
| | | Date now = new Date(); |
| | | agvWaitPakinList.stream().forEach(agvWaitPakin -> { |
| | |
| | | /* |
| | | 生成工作档 |
| | | */ |
| | | private AgvWrkMast createWrkMast(int ioType, long wrkSts, String sourceLocNo, String locNo, String barcode, Date now, Long userId){ |
| | | AgvWrkMast wrkMast = new AgvWrkMast(); |
| | | //生成工作号 |
| | | int workNo = agvCommonService.getWorkNo(WorkNoType.getWorkNoType(ioType)); |
| | | wrkMast.setWrkNo(workNo); |
| | | //工作状态 |
| | | wrkMast.setWrkSts(wrkSts); |
| | | //入出库类型 |
| | | wrkMast.setIoType(ioType); |
| | | wrkMast.setIoTime(now); |
| | | //优先级 |
| | | wrkMast.setIoPri(300.0); |
| | | //源站点 |
| | | wrkMast.setSourceLocNo(sourceLocNo); |
| | | //目标站点 |
| | | wrkMast.setLocNo(locNo); |
| | | //容器编码 |
| | | wrkMast.setBarcode(barcode); |
| | | // 满板:Y |
| | | //wrkMast.setFullPlt("Y"); |
| | | // 拣料 |
| | | //wrkMast.setPicking("N"); |
| | | // 退出 |
| | | //wrkMast.setExitMk("N"); |
| | | // 空板 |
| | | //wrkMast.setEmptyMk("N"); |
| | | //wrkMast.setLinkMis("N"); |
| | | wrkMast.setAppeUser(userId); |
| | | wrkMast.setAppeTime(now); |
| | | wrkMast.setModiUser(userId); |
| | | wrkMast.setModiTime(now); |
| | | if (!agvWrkMastService.insert(wrkMast)) { |
| | | throw new CoolException("保存工作档失败"); |
| | | } |
| | | |
| | | return wrkMast; |
| | | } |
| | | |
| | | /* |
| | | 生成工作档 |
| | | */ |
| | | @Deprecated |
| | | private AgvWrkMast createWrkMast(AgvBasDevp agvBasDevp,AgvLocMast agvLocMast, Date now, Long userId){ |
| | | AgvWrkMast wrkMast = new AgvWrkMast(); |
| | | //生成工作号 |
| | | int workNo = agvCommonService.getWorkNo(0); |
| | | wrkMast.setWrkNo(workNo); |
| | | wrkMast.setIoTime(new Date()); |
| | | wrkMast.setWrkSts(201L); // 工作状态:201.生成入库任务ID |
| | | wrkMast.setIoType(1); // 入出库状态:1.入库 |
| | | // 工作状态:201.生成入库任务ID |
| | | wrkMast.setWrkSts(201L); |
| | | // 入出库状态:1.入库 |
| | | wrkMast.setIoType(1); |
| | | //生成优先级 |
| | | wrkMast.setIoPri(300.0); |
| | | wrkMast.setSourceLocNo(agvBasDevp.getDevNo()); |
| | | wrkMast.setLocNo(agvLocMast.getLocNo()); |
| | | wrkMast.setBarcode(agvBasDevp.getBarcode()); |
| | | wrkMast.setFullPlt("Y"); // 满板:Y |
| | | wrkMast.setPicking("N"); // 拣料 |
| | | wrkMast.setExitMk("N"); // 退出 |
| | | wrkMast.setEmptyMk("N"); // 空板 |
| | | // 满板:Y |
| | | wrkMast.setFullPlt("Y"); |
| | | // 拣料 |
| | | wrkMast.setPicking("N"); |
| | | // 退出 |
| | | wrkMast.setExitMk("N"); |
| | | // 空板 |
| | | wrkMast.setEmptyMk("N"); |
| | | wrkMast.setLinkMis("N"); |
| | | wrkMast.setAppeUser(userId); |
| | | wrkMast.setAppeTime(now); |
| | |
| | | throw new CoolException("保存工作档失败"); |
| | | } |
| | | return wrkMast; |
| | | } |
| | | |
| | | private boolean isPakOut(String locNo, double anfme){ |
| | | AgvLocDetl agvLocDetl = agvLocDetlService.selectOne(new EntityWrapper<AgvLocDetl>().eq("loc_no", locNo)); |
| | | if(agvLocDetl.getAnfme() > anfme){ |
| | | return false; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /* |
| | | AGV生成出库工作档后修改订单信息 |
| | | TODO 与四项库生成出库工作档后修改订单信息整合到一起 |
| | | */ |
| | | private void modifyOrderDetl(LocDto locDto, Long userId){ |
| | | |
| | | if (!BaseController.isJSON(locDto.getOrderNo())) { |
| | | //非合并出库 |
| | | OrderDetl orderDetl = orderDetlService.selectItem(locDto.getOrderNo(), locDto.getMatnr(), locDto.getBatch()); |
| | | if (orderDetl == null) { |
| | | orderDetl = orderDetlService.selectItem(locDto.getOrderNo(), locDto.getMatnr(), null); |
| | | } |
| | | if (!orderDetlService.increase(orderDetl.getOrderId(), orderDetl.getMatnr(), orderDetl.getBatch(), locDto.getAnfme())) { |
| | | throw new CoolException("修改订单明细数量失败"); |
| | | } |
| | | orderService.updateSettle(orderDetl.getOrderId(), 2L, userId); |
| | | }else { |
| | | //合并出库 |
| | | List<OrderDto> orderDtoList = JSON.parseArray(locDto.getOrderNo(), OrderDto.class); |
| | | for (OrderDto orderDto : orderDtoList) { |
| | | OrderDetl orderDetl = orderDetlService.selectItem(orderDto.getOrderNo(), locDto.getMatnr(), locDto.getBatch()); |
| | | if (orderDetl == null) { |
| | | orderDetl = orderDetlService.selectItem(orderDto.getOrderNo(), locDto.getMatnr(), null); |
| | | } |
| | | if (!orderDetlService.increase(orderDetl.getOrderId(), orderDetl.getMatnr(), orderDetl.getBatch(), orderDto.getAnfme())) { |
| | | throw new CoolException("修改订单明细数量失败"); |
| | | } |
| | | orderService.updateSettle(orderDetl.getOrderId(), 2L, userId); |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | } |
| | |
| | | package com.zy.asrs.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.mapper.EntityWrapper; |
| | | import com.baomidou.mybatisplus.mapper.Wrapper; |
| | | import com.baomidou.mybatisplus.plugins.Page; |
| | | import com.baomidou.mybatisplus.service.impl.ServiceImpl; |
| | | import com.core.common.Cools; |
| | | import com.zy.asrs.entity.LocDetl; |
| | | import com.zy.asrs.entity.LocMast; |
| | | import com.zy.asrs.entity.result.StockVo; |
| | | import com.zy.asrs.mapper.LocDetlMapper; |
| | | import com.zy.asrs.service.LocDetlService; |
| | | import com.zy.asrs.service.LocMastService; |
| | | import com.zy.asrs.service.StaDescService; |
| | | import com.zy.common.model.LocDto; |
| | | import com.zy.common.model.QueryStockPreDo; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.ArrayList; |
| | |
| | | |
| | | @Service("locDetlService") |
| | | public class LocDetlServiceImpl extends ServiceImpl<LocDetlMapper, LocDetl> implements LocDetlService { |
| | | |
| | | @Autowired |
| | | private StaDescService staDescService; |
| | | @Autowired |
| | | private LocMastService locMastService; |
| | | |
| | | @Override |
| | | public Page<LocDetl> getStockOut(Page<LocDetl> page) { |
| | |
| | | return result; |
| | | } |
| | | |
| | | //出库 |
| | | public double queryStockAndSetLocDto(String matnr, String batch, String orderNo, List<LocDto> locDtoList, double issued) { |
| | | Wrapper<LocDetl> wrapper = new EntityWrapper<LocDetl>().eq("matnr", matnr).orderBy("modi_time"); |
| | | if(Cools.isEmpty(batch)){ |
| | | wrapper.isNull("batch"); |
| | | }else { |
| | | wrapper.eq("batch",batch); |
| | | } |
| | | |
| | | List<LocDetl> locDetlList = this.selectList(wrapper); |
| | | for (LocDetl locDetl : locDetlList) { |
| | | //判断当前库位货物是否F在库 |
| | | LocMast locMast = locMastService.selectById(locDetl.getLocNo()); |
| | | if(!"F".equals(locMast.getLocSts())){ |
| | | continue; |
| | | } |
| | | if (issued > 0) { |
| | | double anfme = locDetl.getAnfme(); |
| | | int ioType = anfme > issued ? 103 : 101; |
| | | anfme = anfme > issued ? issued : anfme; |
| | | LocDto locDto = new LocDto(locDetl.getLocNo(), locDetl.getMatnr(), locDetl.getMaktx(), locDetl.getBatch(), orderNo, anfme); |
| | | List<Integer> staNos = staDescService.queryOutStaNosByLocNo(locDetl.getLocNo(), ioType); |
| | | locDto.setStaNos(staNos); |
| | | locDtoList.add(locDto); |
| | | // 剩余待出数量递减 |
| | | issued = issued - locDetl.getAnfme(); |
| | | } |
| | | } |
| | | return issued; |
| | | } |
| | | |
| | | @Override |
| | | public Double queryStockAnfme(String matnr, String batch) { |
| | | return this.baseMapper.queryStockAnfme(matnr, batch); |
| | |
| | | |
| | | private List<Integer> staNos; |
| | | |
| | | private List<String> agvStaNos; |
| | | |
| | | private Integer staNo; |
| | | |
| | | private String agvStaNo; |
| | | |
| | | private String specs; |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | public void setAgvStaNos(List<String> agvStaNos){ |
| | | this.agvStaNos = agvStaNos; |
| | | if(!Cools.isEmpty(agvStaNos)){ |
| | | this.agvStaNo = agvStaNos.get(0); |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | |
| | | private Integer staNo; |
| | | |
| | | private String agvStaNo; |
| | | |
| | | private List<LocDto> locDtos; |
| | | |
| | | { |
| | |
| | | this.locDtos.add(locDto); |
| | | } |
| | | |
| | | public TaskDto(String locNo, String agvStaNo, LocDto locDto) { |
| | | this.locNo = locNo; |
| | | this.agvStaNo = agvStaNo; |
| | | this.locDtos.add(locDto); |
| | | } |
| | | |
| | | public TaskDto(String locNo, Integer staNo, List<LocDto> locDtos) { |
| | | this.locNo = locNo; |
| | | this.staNo = staNo; |
| | |
| | | } |
| | | |
| | | function pakoutPreviewDialog(data) { |
| | | for(var i=0; i<data.length; i++){ |
| | | if(!data[i].staNos){ |
| | | data[i].staNos = data[i].agvStaNos; |
| | | data[i].staNo = data[i].agvStaNo; |
| | | } |
| | | } |
| | | var tableCache; |
| | | layer.open({ |
| | | type: 1 |
| | |
| | | {field: 'title', title: '商品', merge: true, align: 'center', width: 350}, |
| | | {field: 'batch', title: '序列码', align: 'center'}, |
| | | {field: 'anfme', title: '数量', align: 'center', width: 90, style: 'font-weight: bold'}, |
| | | {field: 'locNo', title: '货位', align: 'center', width: 100, templet: '#locNoTpl'}, |
| | | {field: 'locNo', title: '货位', align: 'center', templet: '#locNoTpl'}, |
| | | {field: 'staNos', align: 'center', title: '出库站', merge: ['locNo'], templet: '#tbBasicTbStaNos'}, |
| | | // {type: 'checkbox', merge: ['locNo']}, |
| | | ]], |
| | | //cols: getCol(data), |
| | | done: function (res) { |
| | | tableMerge.render(this); |
| | | $('.layui-table-body.layui-table-main').css("overflow", "auto"); |
| | |
| | | let data = tableCache[index]; |
| | | for (let i = 0; i<tableCache.length; i++) { |
| | | if (tableCache[i].locNo === data.locNo) { |
| | | tableCache[i]['staNo'] = Number(obj.elem.value); |
| | | //tableCache[i]['staNo'] = Number(obj.elem.value); |
| | | tableCache[i]['staNo'] = obj.elem.value; |
| | | } |
| | | } |
| | | obj.othis.children().find("input").css("color", "blue"); |
| | |
| | | // 确认 |
| | | form.on('submit(staBatchSelectConfirm)', function (obj) { |
| | | let loadIdx = layer.load(2); |
| | | let batchSta = Number(obj.field.batchSta); |
| | | //let batchSta = Number(obj.field.batchSta); |
| | | let batchSta = obj.field.batchSta; |
| | | let arr = []; |
| | | for (let i = 0; i<tableCache.length; i++) { |
| | | tableCache[i]['staNo'] = batchSta; |
| | |
| | | |
| | | function pakout(tableCache, layerIndex) { |
| | | // let loadIndex = layer.load(2); |
| | | for(var i=0; i<tableCache.length; i++){ |
| | | if(tableCache[i].agvStaNos){ |
| | | tableCache[i].agvStaNo = tableCache[i].staNo; |
| | | tableCache[i].staNos = null; |
| | | tableCache[i].staNo = null; |
| | | } |
| | | } |
| | | notice.msg('正在生成出库任务......', {icon: 4}); |
| | | $.ajax({ |
| | | url: baseUrl + "/out/pakout/auth", |
| | |
| | | } |
| | | |
| | | function pakoutPreviewMergeDialog(data) { |
| | | for(var i=0; i<data.length; i++){ |
| | | if(!data[i].staNos){ |
| | | data[i].staNos = data[i].agvStaNos; |
| | | data[i].staNo = data[i].agvStaNo; |
| | | } |
| | | } |
| | | var mergeTabCache; |
| | | layer.open({ |
| | | type: 1 |
| | |
| | | {field: 'specs', title: '规格', align: 'center'}, |
| | | {field: 'batch', title: '序列码', align: 'center'}, |
| | | {field: 'anfme', title: '数量', align: 'center', width: 90, style: 'font-weight: bold'}, |
| | | {field: 'locNo', title: '货位', align: 'center', width: 100, templet: '#locNoTpl'}, |
| | | {field: 'locNo', title: '货位', align: 'center', templet: '#locNoTpl'}, |
| | | {field: 'staNos', align: 'center', title: '出库站', merge: ['locNo'], templet: '#tbBasicTbStaNos'}, |
| | | // {type: 'checkbox', merge: ['locNo']}, |
| | | ]], |
| | |
| | | let data = mergeTabCache[index]; |
| | | for (let i = 0; i<mergeTabCache.length; i++) { |
| | | if (mergeTabCache[i].locNo === data.locNo) { |
| | | mergeTabCache[i]['staNo'] = Number(obj.elem.value); |
| | | //mergeTabCache[i]['staNo'] = Number(obj.elem.value); |
| | | mergeTabCache[i]['staNo'] = obj.elem.value; |
| | | } |
| | | } |
| | | obj.othis.children().find("input").css("color", "blue"); |
| | |
| | | // 确认 |
| | | form.on('submit(staBatchSelectConfirm)', function (obj) { |
| | | let loadIdx = layer.load(2); |
| | | let batchSta = Number(obj.field.batchSta); |
| | | //let batchSta = Number(obj.field.batchSta); |
| | | let batchSta = obj.field.batchSta; |
| | | let arr = []; |
| | | for (let i = 0; i<mergeTabCache.length; i++) { |
| | | mergeTabCache[i]['staNo'] = batchSta; |
| | |
| | | <input type="radio" name="selectTemplate" value="1" title="模板一" lay-filter="selectTemplateRadio" checked=""> |
| | | <input type="radio" name="selectTemplate" value="2" title="模板二" lay-filter="selectTemplateRadio"> |
| | | <input type="radio" name="selectTemplate" value="3" title="模板三" lay-filter="selectTemplateRadio"> |
| | | <input type="radio" name="selectTemplate" value="4" title="模板四" lay-filter="selectTemplateRadio"> |
| | | </div> |
| | | <fieldset class="layui-elem-field site-demo-button" style="margin-top: 30px;text-align: left;"> |
| | | <legend>打印预览</legend> |
| | |
| | | <tr style="height: 74px"> |
| | | <td align="center" colspan="1">规格</td> |
| | | <td align="center" colspan="1" style="overflow:hidden; white-space:nowrap; text-overflow:ellipsis;">xxxxxxx</td> |
| | | </tr> |
| | | </table> |
| | | </div> |
| | | |
| | | <!-- 预览图 4 --> |
| | | <div id="template-preview-4" class="template-preview" style="display: none"> |
| | | <table class="contain" width="280" style="overflow: hidden;font-size: xx-small;table-layout: fixed;"> |
| | | <tr style="height: 74px"> |
| | | <td align="center" scope="col" >商品</td> |
| | | <td align="center" scope="col" style="">xxxxxx-xx/xx</td> |
| | | <td align="center" scope="col" colspan="2"> |
| | | <img class="template-code template-qrcode" src="" width="80%"> |
| | | <div style="letter-spacing: 1px;margin-top: 1px; text-align: center"><span>xxxxxx</span></div> |
| | | </td> |
| | | </tr> |
| | | <tr style="height: 74px"> |
| | | <td align="center" >规格</td> |
| | | <td align="center" colspan="3" >xxxxxxx</td> |
| | | </tr> |
| | | </table> |
| | | </div> |
| | |
| | | {{/each}} |
| | | </script> |
| | | |
| | | <!-- 模板4 --> |
| | | <script type="text/template" id="templatePreview4" class="template-qrcode"> |
| | | {{#each data}} |
| | | <table class="contain" width="400px" style="overflow: hidden;font-size: xx-small;table-layout: fixed; color:#000;"> |
| | | <tr style="height: 74px;font-size: 18px; font-weight: 400" > |
| | | <td width="50px" align="center" scope="col" colspan="1">商品</td> |
| | | <td width="170px" align="center" scope="col" colspan="1">{{this.maktx}}</td> |
| | | <td align="center" scope="col" colspan="2" > |
| | | <img class="template-code template-qrcode" src="{{this.barcodeUrl}}" width="80%"> |
| | | <div style="letter-spacing: 1px;margin-top: 1px; text-align: center; font-weight: 400"> |
| | | <span>{{this.matnr}}</span> |
| | | </div> |
| | | </td> |
| | | </tr> |
| | | <tr style="height: 74px; font-size: 18px;font-weight: 400"> |
| | | <td width="50px" align="center" colspan="1">规格</td> |
| | | <td align="center" colspan="3" style=" |
| | | overflow:hidden; |
| | | text-overflow:ellipsis; |
| | | -webkit-line-clamp: 3; |
| | | -webkit-box-orient: vertical; |
| | | word-break: break-all; |
| | | ">{{this.specs}}</td> |
| | | </tr> |
| | | </table> |
| | | {{/each}} |
| | | </script> |
| | | |
| | | </body> |
| | | </html> |
| | | |