添加生产入库单功能

This commit is contained in:
曹鹏飞 2025-08-07 11:55:19 +08:00
parent 3d5c33eb40
commit 5f74d354ba
9 changed files with 307 additions and 9 deletions

View File

@ -3,9 +3,11 @@ package com.nflg.wms.admin.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import tech.powerjob.client.PowerJobClient;
@Configuration
@Lazy
public class PowerJobClientConfig {
@Value("${powerjob.worker.server-address}")

View File

@ -1,5 +1,6 @@
package com.nflg.wms.admin.controller;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.idev.excel.EasyExcel;
@ -8,29 +9,27 @@ import cn.idev.excel.metadata.data.ImageData;
import cn.idev.excel.metadata.data.WriteCellData;
import cn.idev.excel.write.metadata.WriteSheet;
import cn.idev.excel.write.metadata.fill.FillConfig;
import com.nflg.wms.admin.service.BinService;
import com.nflg.wms.admin.service.SapService;
import com.nflg.wms.admin.util.NoUtil;
import com.nflg.wms.admin.util.PdfGeneratorUtil;
import com.nflg.wms.admin.util.QRCodeUtil;
import com.nflg.wms.admin.util.ThymeleafUtil;
import com.nflg.wms.common.constant.Constant;
import com.nflg.wms.common.pojo.ApiResult;
import com.nflg.wms.common.pojo.PageData;
import com.nflg.wms.common.pojo.dto.DeliverNormalOrderItemDTO;
import com.nflg.wms.common.pojo.dto.InventoryDTO;
import com.nflg.wms.common.pojo.dto.MaterialQRCodeContentDTO;
import com.nflg.wms.common.pojo.dto.ZWM00MB007DTO;
import com.nflg.wms.common.pojo.qo.InProduceOrderGenerateMaterialsQO;
import com.nflg.wms.common.pojo.qo.InProduceOrderSaveQO;
import com.nflg.wms.common.pojo.qo.InProduceOrderSearchQO;
import com.nflg.wms.common.pojo.qo.*;
import com.nflg.wms.common.pojo.vo.InProduceOrderMaterialVO;
import com.nflg.wms.common.pojo.vo.WmsInProduceOrderItemVO;
import com.nflg.wms.common.util.DateTimeUtil;
import com.nflg.wms.common.util.UserUtil;
import com.nflg.wms.common.util.VUtil;
import com.nflg.wms.repository.entity.WmsBom;
import com.nflg.wms.repository.entity.WmsInProduceOrder;
import com.nflg.wms.repository.entity.WmsInProduceOrderItem;
import com.nflg.wms.repository.service.IWmsBomService;
import com.nflg.wms.repository.service.IWmsInProduceOrderItemService;
import com.nflg.wms.repository.service.IWmsInProduceOrderService;
import com.nflg.wms.repository.entity.*;
import com.nflg.wms.repository.service.*;
import com.nflg.wms.starter.BaseController;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
@ -62,15 +61,40 @@ import java.util.*;
public class InProduceOrderController extends BaseController {
private static final DecimalFormat DF = new DecimalFormat("0.00");
@Resource
private SapService sapService;
@Resource
private IWmsInProduceOrderService produceOrderService;
@Resource
private IWmsInProduceOrderItemService produceOrderItemService;
@Resource
private IWmsBomService bomService;
@Resource
private BinService binService;
@Resource
private IWmsInventoryService inventoryService;
@Resource
private IWmsStorageService storageService;
@Resource
private IDictionaryService dictionaryService;
@Resource
private IWmsWarehouseService warehouseService;
@Resource
private IWmsStorageBinService storageBinService;
@Resource
private IWmsBinService wmsBinService;
/**
* 从SAP查询生产订单信息
* @param no 生产订单号
@ -324,4 +348,126 @@ public class InProduceOrderController extends BaseController {
excelWriter.fill(info, writeSheet);
}
}
/**
* 获取订单信息PDA使用
* @param no 报工单号
*/
@GetMapping("getOrderInfo")
public ApiResult<List<WmsInProduceOrderItemVO>> getOrderInfo(@Valid @RequestParam @NotBlank String no) {
WmsInProduceOrder order = produceOrderService.getByNo(no);
VUtil.trueThrowBusinessError(Objects.isNull(order)).throwMessage("订单不存在");
List<WmsInProduceOrderItemVO> list = produceOrderItemService.getVOByOrderId(order.getId());
list.forEach(it -> {
it.setBinNos(binService.getBinNos(it.getMaterialNo(), it.getFactoryNo(), it.getWarehouseNo()));
});
return ApiResult.success(list);
}
/**
* 收货PDA使用
* @param request 请求参数
*/
@Transactional
@PostMapping("receive")
public ApiResult<Void> receive(@Valid @RequestBody InProduceOrderReceiveQO request){
WmsInProduceOrder order = produceOrderService.getByNo(request.getNo());
VUtil.trueThrowBusinessError(Objects.isNull(order)).throwMessage("订单不存在");
VUtil.trueThrowBusinessError(!Objects.equals(order.getState(), (short)0))
.throwMessage("该订单非待收货状态");
List<WmsInProduceOrderItemVO> list = produceOrderItemService.getVOByOrderId(order.getId());
List<String> materialNos = new ArrayList<>();
list.forEach(it->{
BigDecimal num = BigDecimal.ZERO;
InProduceOrderReceiveMaterialQO materialQO = request.getItems().stream().filter(q -> StrUtil.equals(q.getMaterialNo(), it.getMaterialNo())).findFirst().orElse(null);
if (Objects.isNull(materialQO)) {
materialNos.add(it.getMaterialNo());
} else {
for (String qrCode : materialQO.getQrCodes()) {
MaterialQRCodeContentDTO content = NoUtil.getMaterialQRCodeContent(qrCode);
if (Objects.nonNull(content.getNum())) {
num = num.add(content.getNum());
}
}
if (num.compareTo(it.getNum()) != 0) {
materialNos.add(it.getMaterialNo());
}
//是否更改了储位
syncStorage(it,materialQO.getBinNos());
}
});
VUtil.trueThrowBusinessError(CollectionUtil.isNotEmpty(materialNos))
.throwMessage("以下物料的扫码数量与收货数量不一致:"+StrUtil.join(",", materialNos));
//同步入库信息到SAP
sapService.zwm00_mb107(order.getOrderNo(), UserUtil.getUserName(),list.stream().map(it-> new Zwm00Mb107QO()
.setPWERK(it.getFactoryNo())
.setPSMNG(it.getNum())
.setAMEIN(it.getUnit())
.setLGORT(it.getWarehouseNo())
.setCHARG(it.getBatchNo())).toList(),null
);
order.setState((short)1);
order.setUpdateBy(UserUtil.getUserName());
order.setUpdateTime(LocalDateTime.now());
produceOrderService.updateById(order);
inventoryService.in(list.stream().map(it-> new InventoryDTO()
.setMaterialNo(it.getMaterialNo())
.setNum(it.getNum())
.setFactoryNo(it.getFactoryNo())
.setWarehouseNo(it.getWarehouseNo())
.setBatchNumber(it.getBatchNo())).toList()
);
return ApiResult.success();
}
private void syncStorage(WmsInProduceOrderItemVO it,Set<String> binNos){
Set<String> dbMapBins = storageService.getBinNos(it.getMaterialNo(), it.getFactoryNo(), it.getWarehouseNo());
if (!binNos.equals(dbMapBins)) {
//调用SAP接口保存库位信息
sapService.zwm3A02(it.getFactoryNo(), it.getMaterialNo(), it.getWarehouseNo(), binNos);
//保存库位信息到数据库
DictionaryItem factory = dictionaryService.getItemByCode(Constant.DICTIONARY_FACTORY, it.getFactoryNo());
VUtil.trueThrowBusinessError(Objects.isNull(factory)).throwMessage("工厂(" + it.getFactoryNo() + ")不存在");
WmsWarehouse warehouse = warehouseService.lambdaQuery()
.eq(WmsWarehouse::getFactoryId, factory.getId())
.eq(WmsWarehouse::getNo, it.getWarehouseNo())
.one();
VUtil.trueThrowBusinessError(Objects.isNull(warehouse)).throwMessage("仓库(" + it.getWarehouseNo() + ")不存在");
WmsStorage storage = storageService.lambdaQuery()
.eq(WmsStorage::getMaterialNo, it.getMaterialNo())
.eq(WmsStorage::getWarehouseId, warehouse.getId())
.one();
if (Objects.isNull(storage)) {
storage = new WmsStorage()
.setWarehouseId(warehouse.getId())
.setMaterialNo(it.getMaterialNo())
.setMaterialDesc(it.getMaterialDesc())
.setCreateBy(UserUtil.getUserName())
.setCreateTime(LocalDateTime.now());
storageService.save(storage);
} else {
storageBinService.deleteByStorageId(storage.getId());
}
List<WmsBin> dbBins = wmsBinService.lambdaQuery().in(WmsBin::getNo, binNos).list();
binNos.forEach(binNo -> {
if (dbBins.stream().noneMatch(bin -> StrUtil.equals(bin.getNo(), binNo))) {
WmsBin bin = new WmsBin()
.setNo(binNo)
.setName(binNo)
.setWarehouseId(warehouse.getId())
.setCreateBy(UserUtil.getUserName())
.setCreateTime(LocalDateTime.now());
wmsBinService.save(bin);
dbBins.add(bin);
}
});
WmsStorage finalStorage = storage;
storageBinService.saveBatch(dbBins.stream().map(bin -> new WmsStorageBin()
.setStorageId(finalStorage.getId())
.setBinId(bin.getId()))
.toList()
);
}
}
}

View File

@ -1,10 +1,14 @@
package com.nflg.wms.admin.util;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.nflg.wms.common.pojo.dto.MaterialQRCodeContentDTO;
import com.nflg.wms.common.util.DateTimeUtil;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
public class NoUtil {
@ -40,4 +44,23 @@ public class NoUtil {
public static String getInProduceNo(){
return "IP"+DateTimeUtil.format(LocalDateTime.now(), "yyyyMMddHHmmss");
}
/**
* 解析普通物料二维码内容
* @param qrCode 二维码内容
* @return 解析后的内容
*/
public static MaterialQRCodeContentDTO getMaterialQRCodeContent(String qrCode){
List<String> contents=StrUtil.split(qrCode, "$");
return new MaterialQRCodeContentDTO()
.setUniqNo(CollectionUtil.get(contents, 0))
.setOrderNo(CollectionUtil.get(contents, 1))
.setOrderRowNo(CollectionUtil.get(contents, 2))
.setMaterialNo(CollectionUtil.get(contents, 3))
.setNum(new BigDecimal(CollectionUtil.get(contents, 4)))
.setMaterialDesc(CollectionUtil.get(contents, 5))
.setSupplierNo(CollectionUtil.get(contents, 6))
.setBatchNo(CollectionUtil.get(contents, 7))
.setSerialNo(CollectionUtil.get(contents, 8));
}
}

View File

@ -0,0 +1,56 @@
package com.nflg.wms.common.pojo.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
@Data
@Accessors(chain = true)
public class MaterialQRCodeContentDTO {
/**
* 唯一编号
*/
private String uniqNo;
/**
* 订单编号
*/
private String orderNo;
/**
* 订单行号
*/
private String orderRowNo;
/**
* 物料编号
*/
private String materialNo;
/**
* 数量
*/
private BigDecimal num;
/**
* 物料描述
*/
private String materialDesc;
/**
* 供应商编号
*/
private String supplierNo;
/**
* 批次号
*/
private String batchNo;
/**
* 序列号
*/
private String serialNo;
}

View File

@ -0,0 +1,30 @@
package com.nflg.wms.common.pojo.qo;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import java.util.List;
import java.util.Set;
@Data
public class InProduceOrderReceiveMaterialQO {
/**
* 物料编号
*/
@NotBlank
private String materialNo;
/**
* 储位编号列表
*/
@NotEmpty
private Set<String> binNos;
/**
* 二维码列表
*/
@NotEmpty
private List<String> qrCodes;
}

View File

@ -0,0 +1,23 @@
package com.nflg.wms.common.pojo.qo;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import java.util.List;
@Data
public class InProduceOrderReceiveQO {
/**
* 报工单号
*/
@NotBlank
private String no;
/**
* 物料列表
*/
@NotEmpty
private List<InProduceOrderReceiveMaterialQO> items;
}

View File

@ -48,4 +48,14 @@ public class WmsInProduceOrderItemVO {
* 仓库
*/
private String warehouseNo;
/**
* 储位
*/
private String binNos;
/**
* 批次号
*/
private String batchNo;
}

View File

@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
import com.nflg.wms.common.pojo.qo.InProduceOrderSearchQO;
import com.nflg.wms.repository.entity.WmsInProduceOrder;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
/**
* <p>
@ -17,4 +18,6 @@ import jakarta.validation.Valid;
public interface IWmsInProduceOrderService extends IService<WmsInProduceOrder> {
IPage<WmsInProduceOrder> search(@Valid InProduceOrderSearchQO request);
WmsInProduceOrder getByNo(@Valid @NotBlank String no);
}

View File

@ -35,4 +35,9 @@ public class WmsInProduceOrderServiceImpl extends ServiceImpl<WmsInProduceOrderM
.le(Objects.nonNull(request.getEndDate()), WmsInProduceOrder::getCreateTime, request.getEndDate())
.page(new Page<>(request.getPage(), request.getPageSize()));
}
@Override
public WmsInProduceOrder getByNo(String no) {
return lambdaQuery().eq(WmsInProduceOrder::getNo, no).one();
}
}