123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 |
- package com.ruoyi.ams.xuankuang.service;
- import cn.hutool.core.collection.CollectionUtil;
- import cn.hutool.core.lang.Assert;
- import cn.hutool.core.util.ObjectUtil;
- import com.baomidou.mybatisplus.core.toolkit.IdWorker;
- import com.ruoyi.ams.asn.domain.WmsDocAsnDetails;
- import com.ruoyi.ams.asn.domain.WmsDocAsnHeader;
- import com.ruoyi.ams.asn.service.IWmsDocAsnDetailsService;
- import com.ruoyi.ams.asn.service.IWmsDocAsnHeaderService;
- import com.ruoyi.ams.business.IBusinessService;
- import com.ruoyi.ams.config.domain.dto.AgvCallDTO;
- import com.ruoyi.ams.config.domain.dto.AgvCallItemDTO;
- import com.ruoyi.ams.config.domain.dto.LotattDTO;
- import com.ruoyi.ams.inv.service.IInvLotLocIdService;
- import com.ruoyi.ams.order.domain.WmsDocOrderDetails;
- import com.ruoyi.ams.order.domain.WmsDocOrderHeader;
- import com.ruoyi.ams.order.service.IWmsDocOrderDetailsService;
- import com.ruoyi.ams.order.service.IWmsDocOrderHeaderService;
- import com.ruoyi.ams.task.service.IWcsTaskService;
- import com.ruoyi.ams.xuankuang.domain.form.AgvInTaskForm;
- import com.ruoyi.ams.xuankuang.domain.form.OutTaskForm;
- import com.ruoyi.ams.xuankuang.domain.vo.WcsResponseVo;
- import com.ruoyi.base.constant.Constant;
- import com.ruoyi.base.domain.BaseLocationInfo;
- import com.ruoyi.base.domain.BaseSku;
- import com.ruoyi.base.domain.vo.BaseLocationLotattDTO;
- import com.ruoyi.base.service.IBaseLocationInfoService;
- import com.ruoyi.base.service.IBaseSkuService;
- import com.ruoyi.base.utils.IdSequenceUtils;
- import com.ruoyi.common.core.domain.AjaxResult;
- import com.ruoyi.common.utils.StringUtils;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
- import java.math.BigDecimal;
- import java.util.ArrayList;
- import java.util.List;
- /**
- * @author Jwk
- * @version 1.0
- * @date 2023/6/6 13:35
- */
- @Slf4j
- @Service
- public class AgvCallProxyService {
- @Autowired
- private IBusinessService iBusinessService;
- @Autowired
- BaseLocationInfoSubService baseLocationInfoSubService;
- @Autowired
- WmsDocAsnSubService wmsDocAsnSubService;
- @Autowired
- private IBaseSkuService iBaseSkuService;
- @Autowired
- private IdSequenceUtils idSequenceUtils;
- @Autowired
- private IWmsDocAsnHeaderService iWmsDocAsnHeaderService;
- @Autowired
- private IWmsDocAsnDetailsService iWmsDocAsnDetailsService;
- @Autowired
- private IWmsDocOrderHeaderService iWmsDocOrderHeaderService;
- @Autowired
- private IWmsDocOrderDetailsService iWmsDocOrderDetailsService;
- @Autowired
- private WmsDocOrderSubService wmsDocOrderSubService;
- @Autowired
- private WcsTaskSubService wcsTaskSubService;
- @Autowired
- private WmsToWcsApiService wmsToWcsApiService;
- @Autowired
- private IBaseLocationInfoService iBaseLocationInfoService;
- @Autowired
- private InvLotLocIdSubService invLotLocIdSubService;
- @Autowired
- private IWcsTaskService iWcsTaskService;
- @Autowired
- private IInvLotLocIdService invLotLocIdService;
- /**
- * 主方法:桶装入库
- * @param palletNo 入库托盘号
- * @param materialType 物料类型 丁胺黑药类型:5
- * @param agvSourceLocationId agv的起始点位
- * @param quantity 数量
- */
- @Transactional(rollbackFor = RuntimeException.class)
- public void bucketIntoStorage(String palletNo, String materialType,
- String agvSourceLocationId, Double quantity) {
- //1.预备参数设置
- BaseSku baseSku = iBaseSkuService.selectSkuByMaterialType(materialType);
- Assert.isTrue(ObjectUtil.isNotNull(baseSku) && StringUtils.isNotBlank(baseSku.getSku()), "the materialType is illegal");
- String asnNo = idSequenceUtils.generateId(Constant.ID_TYPE.ASNNO.getDesc());
- Assert.isTrue(ObjectUtil.isNotNull(quantity) && quantity > 0, "quantity is illegal");
- BigDecimal quantityDecimal = new BigDecimal(quantity);
- //2. 获取agv的库位,并创建agv的wcs任务
- String agvTargetLocationId = String.valueOf(getAgvLocationId("bucketLocationIdList"));
- String agvTaskNo = IdWorker.getIdStr();
- addWcsTask(agvTaskNo, agvSourceLocationId, agvTargetLocationId,
- asnNo, palletNo, Constant.TASK_STS.TASK_CREATE.getLongValue(), "AGV入库任务下发", Constant.TaskType.AGV.getDesc());
- //3.入库单创建
- WmsDocAsnHeader wmsDocAsnHeader =
- iWmsDocAsnHeaderService.createAsnHeader(asnNo, Constant.ASN_TYP.TZ.getValue(), Constant.ASN_STS.STS00.getValue());
- WmsDocAsnDetails wmsDocAsnDetail =
- iWmsDocAsnDetailsService.createAsnDetail(asnNo, baseSku.getSku(), quantityDecimal);
- //4. 根据入库单进行agv的任务下发,通知wcs并生成wcs任务;agv的目标点则是wcs任务的起始点位
- String taskNo = IdWorker.getIdStr();
- WcsResponseVo wcsResponseVo = noticeBucketIntoLocTask(taskNo, agvTargetLocationId, asnNo, palletNo, materialType, quantity);
- if (!wcsResponseVo.isSuccess()) {
- wmsDocAsnHeader.setNotes(wcsResponseVo.getMessage());
- iWmsDocAsnHeaderService.updateWmsDocAsnHeader(wmsDocAsnHeader);
- wcsTaskSubService.callBack(taskNo, Constant.TASK_STS.TASK_CANCEL.getValue(), null);
- }
- wmsDocAsnHeader.setAsnStatus(Constant.ASN_STS.STS10.getValue());
- wmsDocAsnDetail.setLineStatus(Constant.ASN_STS.STS10.getValue());
- iWmsDocAsnDetailsService.updateWmsDocAsnDetails(wmsDocAsnDetail);
- iWmsDocAsnHeaderService.updateWmsDocAsnHeader(wmsDocAsnHeader);
- }
- /**
- * 主方法:桶装出库
- * @param materialType 物料类型,丁胺黑药默认传5
- * @param targetLocationId 出库的最终目标库位
- * @param quantity 数量 不能大于4
- */
- @Transactional(rollbackFor = RuntimeException.class)
- public void bucketOutOfStorage(String materialType, String targetLocationId, Double quantity) {
- //1.预备参数设置
- BaseSku baseSku = iBaseSkuService.selectSkuByMaterialType(materialType);
- Assert.isTrue(ObjectUtil.isNotNull(baseSku) && StringUtils.isNotBlank(baseSku.getSku()), "the materialType is illegal");
- String orderNo = idSequenceUtils.generateId(Constant.ID_TYPE.ORDERNO.getDesc());
- Assert.isTrue(ObjectUtil.isNotNull(quantity) && quantity > 0, "quantity is illegal");
- BigDecimal quantityDecimal = new BigDecimal(quantity);
- //2. 获取agv的库位,并创建agv的wcs任务
- String agvSourceLocationId = String.valueOf(getAgvLocationId("bucketLocationIdList"));
- String agvTaskNo = IdWorker.getIdStr();
- addWcsOutTask(agvTaskNo, agvSourceLocationId, targetLocationId,
- orderNo, Constant.TASK_STS.TASK_CREATE.getLongValue(), "AGV出库任务下发", Constant.TaskType.AGV.getDesc());
- //3.出库单创建
- WmsDocOrderHeader docOrderHeader =
- iWmsDocOrderHeaderService.createOrderHeader(orderNo, Constant.ORDER_TYP.TZ.getValue(), Constant.ORDER_STS.STS00.getValue(), baseSku.getSku());
- WmsDocOrderDetails docOrderDetail =
- iWmsDocOrderDetailsService.createOrderDetail(orderNo, baseSku.getSku(), quantityDecimal);
- //4. 根据出库单进行出库任务下发,通知wcs并生成wcs任务;改变订单的状态
- List<BaseLocationLotattDTO> baseLocationLotattList = wmsDocOrderSubService.addConfirmAllocationAuto(orderNo);
- List<BaseLocationLotattDTO> filteredBaseLocationLotattList = wmsDocOrderSubService.filterInv(baseLocationLotattList, orderNo);
- Assert.isTrue(CollectionUtil.isNotEmpty(filteredBaseLocationLotattList), "filteredBaseLocationLotattList is empty");
- //int errorCount = 0;
- for (BaseLocationInfo baseLocationInfo : filteredBaseLocationLotattList){
- //每个推荐的出库库存都创建一个wcs任务,agv的起始点则是wcs任务的目标点位
- //通知wcs的桶装出库的任务
- WcsResponseVo wcsResponseVo = noticeBucketOutLocTask(IdWorker.getIdStr(), agvSourceLocationId, orderNo, materialType, quantity, baseLocationInfo);
- if (!wcsResponseVo.isSuccess()) {
- //errorCount++;
- docOrderHeader.setRemark(wcsResponseVo.getMessage());
- iWmsDocOrderHeaderService.updateWmsDocOrderHeader(docOrderHeader);
- }
- }
- //此处屏蔽的代码:代表只有在全部同步失败的情况下,不改变单头和明细的状态
- //if(errorCount == filteredBaseLocationLotattList.size()) return;
- docOrderHeader.setOrderStatus(Constant.ASN_STS.STS10.getValue());
- docOrderDetail.setLineStatus(Constant.ASN_STS.STS10.getValue());
- iWmsDocOrderDetailsService.updateWmsDocOrderDetails(docOrderDetail);
- iWmsDocOrderHeaderService.updateWmsDocOrderHeader(docOrderHeader);
- }
- /**
- * 主方法:桶装越库
- * @param palletNo 托盘号
- * @param materialType 物料类型 丁胺黑药类型5
- * @param sourceLocationId 起始库位
- * @param targetLocationId 目标库位
- * @param quantity 数量 不大于4
- */
- public void bucketCrossStorage(String palletNo, String materialType, String sourceLocationId, String targetLocationId, Double quantity) {
- //1.预备参数设置
- Assert.isTrue(ObjectUtil.isNotNull(quantity) && quantity > 0, "quantity is illegal");
- BaseSku baseSku = iBaseSkuService.selectBaseSkuByMaterialType(materialType);
- Assert.isTrue(ObjectUtil.isNotNull(baseSku) && StringUtils.isNotBlank(baseSku.getSku()), "the materialType is illegal");
- BigDecimal quantityDecimal = new BigDecimal(quantity);
- //2.入库单创建
- String asnNo = idSequenceUtils.generateId(Constant.ID_TYPE.ASNNO.getDesc());
- iWmsDocAsnHeaderService.createAsnHeader(asnNo, Constant.ASN_TYP.TZ.getValue(), Constant.ASN_STS.STS40.getValue());
- iWmsDocAsnDetailsService.createAsnDetail(asnNo, baseSku.getSku(), quantityDecimal);
- //3.出库单创建
- String orderNo = idSequenceUtils.generateId(Constant.ID_TYPE.ORDERNO.getDesc());
- iWmsDocOrderHeaderService.createOrderHeader(orderNo, Constant.ORDER_TYP.TZ.getValue(), Constant.ORDER_STS.STS40.getValue(), baseSku.getSku());
- iWmsDocOrderDetailsService.createOrderDetail(orderNo, baseSku.getSku(), quantityDecimal);
- //2. 获取agv的库位,并创建agv的wcs任务
- String agvTaskNo = IdWorker.getIdStr();
- wcsTaskSubService.addCrossWcsTask(agvTaskNo, sourceLocationId, targetLocationId,
- asnNo, palletNo, orderNo, Constant.TASK_STS.TASK_WAIT.getLongValue(), "agv越库任务下发");
- }
- /**
- * 桶装出库
- *
- * @param locationFrom
- * @param locationTo
- * @return
- */
- public AjaxResult barrelsOutOfStorage(String locationFrom, String locationTo, String palletNo, String wcsId) {
- AgvCallDTO agvCallDTO = new AgvCallDTO();
- agvCallDTO.setLocationFrom(locationFrom);
- agvCallDTO.setLocationTo(locationTo);
- List<AgvCallItemDTO> agvCallItemDTOList = new ArrayList<>();
- LotattDTO lotattDTO = new LotattDTO();
- lotattDTO.setLotatt07(palletNo);
- lotattDTO.setLotatt08(wcsId);
- AgvCallItemDTO agvCallItemDTO = new AgvCallItemDTO();
- agvCallItemDTO.setSku("C4H9O2PSSNH4"); // 丁铵黑药
- agvCallItemDTO.setLotattDTO(lotattDTO);
- agvCallItemDTOList.add(agvCallItemDTO);
- agvCallDTO.setAgvCallItemDTOList(agvCallItemDTOList);
- return iBusinessService.agvCall(Constant.FLOW_CONFIG_ID.ONE.getValue(), agvCallDTO);
- }
- private WcsResponseVo noticeBucketOutLocTask(String taskNo, String bucketCacheLocationId, String orderNo, String materialType, Double quantity, BaseLocationInfo baseLocationInfo) {
- BaseSku baseSku = iBaseSkuService.selectSkuByMaterialType(materialType);
- Assert.isTrue(ObjectUtil.isNotNull(baseSku) && StringUtils.isNotBlank(baseSku.getSku()) , "baseSku is null");
- //1.生成一个wcs任务
- String locationInfoId = String.valueOf(baseLocationInfo.getId());
- addWcsOutTask(taskNo, locationInfoId, bucketCacheLocationId, orderNo, 10L, "桶装料出库任务", Constant.TaskType.RGV.getDesc());
- //修改出库出库存的traceId TODO
- invLotLocIdService.operateTraceIdByLocationId(locationInfoId, taskNo);
- //4.组装wcs任务请求参数并同步当前的wcs任务
- OutTaskForm outTaskForm = assemblyOutTaskForm(taskNo, orderNo, baseSku.getSkuType(), materialType, quantity, baseLocationInfo);
- return wmsToWcsApiService.wmsOutTask(outTaskForm);
- }
- private AjaxResult addWcsTask(String taskNo, String locationFrom, String locationTo
- , String asnNo, String palletNo, Long state, String remake, String taskType) {
- return wcsTaskSubService.addWcsTask(taskNo, locationFrom, locationTo, asnNo, palletNo, StringUtils.EMPTY, state, remake, taskType);
- }
- private AjaxResult addWcsOutTask(String taskNo, String locationFrom, String locationTo,
- String orderNo, Long status, String remark, String taskType) {
- return wcsTaskSubService.addWcsOutTask(taskNo, locationFrom, locationTo
- , orderNo, StringUtils.EMPTY, StringUtils.EMPTY, status, remark, taskType);
- }
- private WcsResponseVo noticeBucketIntoLocTask(String taskNo, String bucketCacheLocationId, String asnNo, String palletNo, String materialType, Double quantity) {
- BaseSku baseSku = iBaseSkuService.selectBaseSkuByMaterialType(materialType);
- Assert.isTrue(ObjectUtil.isNotNull(baseSku), "baseSku is null");
- // 1.推荐目标库位
- BaseLocationInfo baseLocationInfo = baseLocationInfoSubService.recommendAReceiptLocation(baseSku.getSku());
- Assert.isTrue(ObjectUtil.isNotNull(baseLocationInfo), "baseLocationLotatt is null");
- // 2.桶装接驳位生成库存
- invLotLocIdSubService.initInv(bucketCacheLocationId, baseSku.getSku(), palletNo, asnNo, taskNo, quantity);
- // 3.生成任务
- addWcsTask(taskNo, bucketCacheLocationId
- , String.valueOf(baseLocationInfo.getId()), asnNo, palletNo,
- Constant.TASK_STS.TASK_PUBILSH.getLongValue(), "桶装料入库任务",
- Constant.TaskType.RGV.getDesc());
- //4.同步当前的wcs任务
- AgvInTaskForm agvInTaskForm = assemblyAgvInTaskForm(taskNo, asnNo, materialType, quantity, palletNo, baseLocationInfo);
- return wmsToWcsApiService.wmsAgvInTask(agvInTaskForm);
- }
- private OutTaskForm assemblyOutTaskForm(String taskNo, String orderNo, String skuType, String materialType, Double quantity, BaseLocationInfo baseLocationInfo) {
- OutTaskForm outTaskForm = new OutTaskForm();
- outTaskForm.setDocNo(orderNo);
- outTaskForm.setTaskNo(taskNo);
- outTaskForm.setRow(Integer.valueOf(baseLocationInfo.getRowIndex()));
- outTaskForm.setCol(Integer.parseInt(baseLocationInfo.getRowNo()));
- outTaskForm.setFloor(Integer.parseInt(baseLocationInfo.getShiftNo()));
- outTaskForm.setPackageType(Integer.valueOf(skuType));
- outTaskForm.setMaterial(Integer.valueOf(materialType));
- outTaskForm.setTotal(quantity.intValue());
- return outTaskForm;
- }
- private AgvInTaskForm assemblyAgvInTaskForm(String taskNo, String asnNo, String materialType, Double quantity, String palletNo, BaseLocationInfo baseLocationInfo) {
- AgvInTaskForm agvInTaskForm = new AgvInTaskForm();
- agvInTaskForm.setTaskNo(taskNo);
- agvInTaskForm.setAgvId("1");
- agvInTaskForm.setMaterial(Integer.valueOf(materialType));
- agvInTaskForm.setDocNo(asnNo);
- agvInTaskForm.setNum(quantity.intValue());
- agvInTaskForm.setPalletId(palletNo);
- agvInTaskForm.setRow(Integer.valueOf(baseLocationInfo.getRowIndex()));
- agvInTaskForm.setCol(Integer.valueOf(baseLocationInfo.getRowNo()));
- agvInTaskForm.setFloor(Integer.valueOf(baseLocationInfo.getShiftNo()));
- return agvInTaskForm;
- }
- private Long getAgvLocationId(String subSceneCode) {
- List<Long> bucketLocationIdList = iWcsTaskService.getBucketLocationIdList(subSceneCode);
- Assert.isTrue(CollectionUtil.isNotEmpty(bucketLocationIdList), "bucketLocationIdList is empty");
- BaseLocationInfo agvTargetLocationInfo = iBaseLocationInfoService.selectBaseLocationInfoById(bucketLocationIdList.get(0));
- return ObjectUtil.isNotNull(agvTargetLocationInfo) ? agvTargetLocationInfo.getId() : Constant.DRUM_CONNECTORS;
- }
- }
|