Compare commits

..

11 Commits

16 changed files with 169 additions and 63 deletions

29
.gitignore vendored
View File

@ -1,17 +1,6 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
logs/
*.log
### IntelliJ IDEA ###
.idea
@ -19,17 +8,5 @@ target/
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
/dev_jco_rfc.log
logs
.vscode/

View File

@ -12,7 +12,10 @@ import com.nflg.wms.common.pojo.ApiResult;
import com.nflg.wms.common.pojo.PageData;
import com.nflg.wms.common.pojo.dto.*;
import com.nflg.wms.common.pojo.qo.*;
import com.nflg.wms.common.pojo.vo.*;
import com.nflg.wms.common.pojo.vo.ComponentOutboundEditVO;
import com.nflg.wms.common.pojo.vo.ComponentOutboundItemVO;
import com.nflg.wms.common.pojo.vo.ComponentOutboundVO;
import com.nflg.wms.common.pojo.vo.ScanCodeVO;
import com.nflg.wms.common.util.PageUtil;
import com.nflg.wms.common.util.UserUtil;
import com.nflg.wms.common.util.VUtil;
@ -24,7 +27,6 @@ import com.nflg.wms.repository.service.IWmsComponentOutboundItemService;
import com.nflg.wms.repository.service.IWmsComponentOutboundService;
import com.nflg.wms.repository.service.IWmsComponentPackingItemService;
import com.nflg.wms.repository.service.IWmsComponentPackingService;
import com.nflg.wms.starter.annotation.ApiMark;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
@ -32,9 +34,10 @@ import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;
/**
* 零部件出库单
@ -113,6 +116,39 @@ public class ComponentOutboundController {
return ApiResult.success(vos);
}
/**
* 出库单冲销
*
* @param request 确认出库单的参数对象
*/
@PostMapping("reverse")
public ApiResult<Void> reverse(@Valid @RequestBody PackingOutBoundReverseQO request) {
// 通过出库单ID获取到出库单
WmsComponentOutbound outbound = wmsComponentOutboundService.getById(request.getId());
VUtil.trueThrowBusinessError(Objects.isNull(outbound)).throwMessage("出库单不存在");
VUtil.trueThrowBusinessError(outbound.getIsReverse()).throwMessage("此出库单已经被冲销,不可以二次冲销");
List<WmsComponentOutboundItem> outboundItems = wmsComponentOutboundItemService.lambdaQuery()
.eq(WmsComponentOutboundItem::getOutboundId, request.getId())
.list();
VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(outboundItems)).throwMessage("无有效的出库单明细项");
// 组装库存信息
List<InventoryDTO> inventoryDTOS = new ArrayList<>();
for (WmsComponentOutboundItem item : outboundItems) {
List<WmsComponentOutboundScanCodes> codes = wmsComponentOutboundScanCodesService.findByOutboundItemId(item.getId());
VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(codes)).throwMessage("无有效的扫码记录");
for (WmsComponentOutboundScanCodes code : codes) {
setInventoryDTO(inventoryDTOS, item.getIdnrk(), outbound.getFactoryNo(), item.getLgort(), code.getBatchNumber(), code.getCodeNum());
}
}
// 组装SAP的信息
ZWM3A20DTO zwm3a20DTO = new ZWM3A20DTO()
.setIType("B")
.setIvDelivery(outbound.getVbelv());
componentOutboundControllerService.reverse(outbound.getId(), outbound.getPackingId(), inventoryDTOS, zwm3a20DTO);
return ApiResult.success();
}
/**
* 确认出库单
*
@ -126,16 +162,35 @@ public class ComponentOutboundController {
VUtil.trueThrowBusinessError(Objects.isNull(packing)).throwMessage("此装箱单不存在");
VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(request.getItems())).throwMessage("无发货详情信息");
List<Long> packingItemId = request.getItems()
.stream()
.map(ComponentOutboundItemInputQO::getPackingItemId)
.toList();
List<WmsComponentPackingItem> packingItems = wmsComponentPackingItemService
.lambdaQuery()
.in(WmsComponentPackingItem::getId, packingItemId)
.eq(WmsComponentPackingItem::getPackingId, packing.getId())
.list();
VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(packingItems)).throwMessage("无法找到有效的装箱单详情");
//判断是否存在了相同的交货单了
WmsComponentOutbound outboundSelect = wmsComponentOutboundService.lambdaQuery()
.eq(WmsComponentOutbound::getVbelv, packing.getVbelv())
.eq(WmsComponentOutbound::getIsReverse, false)
.one();
VUtil.trueThrowBusinessError(Objects.nonNull(outboundSelect), () -> "交货单已出库,单号为【" + outboundSelect.getOutboundNo() + "");
//判断数量是否一致且已经存在了相同的收货单了
for (WmsComponentPackingItem item : packingItems) {
List<ComponentOutboundItemInputQO> items = request.getItems()
.stream()
.filter(d -> d.getPackingItemId().equals(item.getId()))
.toList();
VUtil.trueThrowBusinessError(CollectionUtil.isEmpty(items))
.throwMessage("物料【" + item.getIdnrk() + "】的实际出库数量为0小于了出库数量【" + item.getMenge() + "");
BigDecimal totalCodeNum = request.getItems().stream()
.flatMap(i -> i.getScanCodes() != null ? i.getScanCodes().stream() : Stream.empty())
.map(ScanCodeQO::getCodeNum)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
VUtil.trueThrowBusinessError(item.getMenge().subtract(totalCodeNum).compareTo(BigDecimal.ZERO) != 0)
.throwMessage("物料【" + item.getIdnrk() + "】的实际出库数量为【" + totalCodeNum + "】,小于了出库数量【" + item.getMenge() + "");
}
WmsComponentOutbound outbound = setWmsComponentOutbound(packing);
List<WmsComponentOutboundItem> outboundItems = new ArrayList<>();
List<WmsComponentOutboundScanCodes> outboundScanCodes = new ArrayList<>();
@ -156,19 +211,15 @@ public class ComponentOutboundController {
//处理条码先根据批次号序列号进行一次数量汇总
if (CollectionUtil.isNotEmpty(item.getScanCodes())) {
List<ScanCodeQO> scanCodesGroup=new ArrayList<>();
for (ScanCodeQO code : item.getScanCodes())
{
ScanCodeQO codeItem=scanCodesGroup.stream().filter(c->c.getBatchNumber().equals(code.getBatchNumber())
List<ScanCodeQO> scanCodesGroup = new ArrayList<>();
for (ScanCodeQO code : item.getScanCodes()) {
ScanCodeQO codeItem = scanCodesGroup.stream().filter(c -> c.getBatchNumber().equals(code.getBatchNumber())
&& c.getSerialNumber().equals(code.getSerialNumber())
).findFirst().orElse(null);
if(Objects.isNull(codeItem))
{
if (Objects.isNull(codeItem)) {
scanCodesGroup.add(code);
}
else
{
} else {
codeItem.setCodeNum(codeItem.getCodeNum().add(code.getCodeNum()));
}
}
@ -210,14 +261,12 @@ public class ComponentOutboundController {
}
}
for (ScanCodeQO code : scanCodesGroup) {
// VUtil.trueThrowBusinessError(codeIds.contains(code.getCodeId())).throwMessage("物料[" + outboundItem.getIdnrk() + "]的条码[" + code.getCodeId() + "]被重复使用");
// codeIds.add(code.getCodeId());
// 组装条码信息
WmsComponentOutboundScanCodes scanCodes = new WmsComponentOutboundScanCodes();
scanCodes.setOutboundItemId(outboundItem.getId())
.setCodeId(code.getCodeId())
.setOutboundId(outbound.getId())
.setSerialNumbers(code.getSerialNumber())
.setCodeNum(code.getCodeNum())
.setBatchNumber(code.getBatchNumber())
@ -226,17 +275,10 @@ public class ComponentOutboundController {
//组装下库存信息
setInventoryDTO(inventories, outboundItem.getIdnrk(),
packing.getFactoryNo(), outboundItem.getLgort(), code.getBatchNumber(), code.getCodeNum());
}
} else {
setInventoryDTO(inventories, outboundItem.getIdnrk(), packing.getFactoryNo(), outboundItem.getLgort(), "", outboundItem.getOutQty());
set3A20Item("", outboundItem, outboundItem.getOutQty(), zwm3a20DTO);
}
}
// 判断下当前的条码是否有已经使用过得
// List<WmsComponentOutboundScanCodes> existScanCodes = wmsComponentOutboundScanCodesService.findByCodeIdIn(codeIds);
// VUtil.trueThrowBusinessError(CollectionUtil.isNotEmpty(existScanCodes)).throwMessage("存在已经使用过的条码");
componentOutboundControllerService.confirmPda(outbound, outboundItems, outboundScanCodes, zwm3a20DTO, inventories);
return ApiResult.success();
}
@ -270,6 +312,7 @@ public class ComponentOutboundController {
.setPackingId(packing.getId())
.setCreateName(UserUtil.getUserName())
.setCreateId(UserUtil.getUserId())
.setIsReverse(false)
.setCreateTime(LocalDateTime.now());
return outbound;
}
@ -308,6 +351,9 @@ public class ComponentOutboundController {
return outboundItem;
}
/*
组装库存信息
*/
private void setInventoryDTO(List<InventoryDTO> inventories, String materialNo,
String factoryNo, String warehouseNo, String batchNumber, BigDecimal outQty
) {

View File

@ -96,6 +96,14 @@ public class ComponentPackingController {
*/
@PostMapping("getorders")
public ApiResult<ZWM3A19DTO> getComponentOrders(@Valid @RequestBody ComponentOrderQO request) {
// 判断交货单号是否已经存在了
WmsComponentPacking packing = wmscomponentPackingService.lambdaQuery()
.eq(WmsComponentPacking::getVbelv, request.getVbelv())
.eq(WmsComponentPacking::getIsCompleted, 2)
.one();
VUtil.trueThrowBusinessError(Objects.nonNull(packing))
.throwMessage("已存在相同的交货单,单号为【" + packing.getNo() + "】,状态为【" + (packing.getIsCompleted() == 0 ? "未出库" : "已出库") + "");
ZWM3A19DTO result = sapService.zwm3a19(request.getVbelv(), request.getWerks());
VUtil.trueThrowBusinessError(StrUtil.isBlank(result.getHeadDTO().getWbstk())
|| result.getHeadDTO().getWbstk().equalsIgnoreCase("C"))
@ -137,7 +145,7 @@ public class ComponentPackingController {
public ApiResult<Void> deletePacking(@Valid @RequestBody List<Long> ids) {
//首先判断是否存在已完成的单据
List<WmsComponentPacking> packingList = wmscomponentPackingService.lambdaQuery()
.eq(WmsComponentPacking::getIsCompleted, 2)
.ne(WmsComponentPacking::getIsCompleted, 0)
.in(WmsComponentPacking::getId, ids)
.list();
VUtil.trueThrowBusinessError(CollectionUtil.isNotEmpty(packingList)).throwMessage("存在已完成的装车单,请勿删除");

View File

@ -15,6 +15,11 @@ public class WmsComponentOutboundScanCodes {
@Id
private String id;
/**
* 出库单ID
*/
private Long outboundId;
/***
* 出库单的单行ID号
*

View File

@ -12,6 +12,9 @@ import java.util.List;
@Repository
public interface WmsComponentOutboundScanCodesRepository extends MongoRepository<WmsComponentOutboundScanCodes, String> {
List<WmsComponentOutboundScanCodes> findByOutboundItemId(Long outboundItemId);
List<WmsComponentOutboundScanCodes> findByoutboundId(Long outboundId);
List<WmsComponentOutboundScanCodes> findByCodeIdIn(List<String> attr0);
}

View File

@ -10,7 +10,10 @@ import com.nflg.wms.common.pojo.dto.ZWM3A20DTO;
import com.nflg.wms.common.pojo.qo.ComponentOutboundInputQO;
import com.nflg.wms.common.pojo.qo.ComponentOutboundItemInputQO;
import com.nflg.wms.common.pojo.qo.ComponentOutboundQO;
import com.nflg.wms.common.pojo.qo.PackingOutBoundReverseQO;
import com.nflg.wms.common.pojo.vo.ComponentOutboundVO;
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.*;
import com.nflg.wms.repository.service.*;
@ -19,6 +22,7 @@ import jakarta.validation.Valid;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@ -82,4 +86,36 @@ public class ComponentOutboundControllerService {
wmsComponentOutboundScanCodesService.insert(outboundScanCodes);
}
}
@Transactional
public void reverse(Long outboundId, Long packingId, List<InventoryDTO> inventories, ZWM3A20DTO zwm3a20DTO) {
//修改出库单的冲销状态为true
wmsComponentOutboundService.lambdaUpdate()
.set(WmsComponentOutbound::getIsReverse, true)
.set(WmsComponentOutbound::getModifyId, UserUtil.getUserId())
.set(WmsComponentOutbound::getModifyName, UserUtil.getUserName())
.set(WmsComponentOutbound::getModifyTime, LocalDateTime.now())
.eq(WmsComponentOutbound::getId, outboundId)
.update();
// 修改包装单的冲销状态为true
wmscomponentPackingService.lambdaUpdate()
.set(WmsComponentPacking::getIsCompleted, 1)
.set(WmsComponentPacking::getModifyId, UserUtil.getUserId())
.set(WmsComponentPacking::getModifyName, UserUtil.getUserName())
.set(WmsComponentPacking::getModifyTime, LocalDateTime.now())
.eq(WmsComponentPacking::getId, packingId)
.update();
//修改库存信息
if (CollectionUtil.isNotEmpty(inventories)) {
inventoryService.in(inventories);
}
//SAP冲销
Pair<String, String> result = sapService.zwm3a20(zwm3a20DTO);
wmsComponentOutboundService.lambdaUpdate()
.set(WmsComponentOutbound::getMaterialDoc, result.getKey())
.set(WmsComponentOutbound::getMaterialDocYear, result.getValue())
.eq(WmsComponentOutbound::getId, outboundId)
.update();
}
}

View File

@ -1225,6 +1225,7 @@ public class SapService {
JCoFunction function = exec("ZWM3A20", parameters, tables);
JCoStructure structure = function.getExportParameterList().getStructure("OUTPUT");
print("输出参数OUTPUT", structure);
VUtil.trueThrowBusinessError(!StrUtil.equals(structure.getString("TYPE"), "S"))
.throwMessage("SAP错误" + structure.getString("MSG"));
return Pair.of(structure.getString("MAT_DOC"), structure.getString("DOC_YEAR"));

View File

@ -25,7 +25,7 @@ import java.util.concurrent.TimeUnit;
public class DeployTest {
private static final String serviceName = "admin";
private static final String localPath = System.getProperty("user.dir") + "\\target\\";
private static final String localPath = System.getProperty("user.dir") + "//target//";
private static final String remotePath = "/mnt/app/wms/" + serviceName + "/";
private static final String jarName = "nflg-wms-" + serviceName + "-1.0.0-SNAPSHOT.jar";

View File

@ -0,0 +1,11 @@
package com.nflg.wms.common.pojo.qo;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true)
public class PackingOutBoundReverseQO {
// 出库单ID
private Long id;
}

View File

@ -150,4 +150,9 @@ public class ComponentOutboundVO {
private String modifyName;
private LocalDateTime modifyTime;
/**
* 是否冲销
*/
private Boolean isReverse;
}

View File

@ -124,7 +124,7 @@ public class ComponentPackingVO {
private String wbstk;
/**
* 0 未出库1 完成出库
* 0 未出库1 对冲2 出库完成
*/
private Short isCompleted;
@ -136,4 +136,5 @@ public class ComponentPackingVO {
* 所属工厂
*/
private String factoryNo;
}

View File

@ -7,6 +7,8 @@ import com.nflg.wms.common.function.ThrowBusinessExceptionFunction;
import com.nflg.wms.common.function.ThrowExceptionFunction;
import com.nflg.wms.common.function.TrueHandleFunction;
import java.util.function.Supplier;
public class VUtil {
public static ThrowBusinessExceptionFunction trueThrowBusinessError(boolean flag) {
@ -18,6 +20,12 @@ public class VUtil {
};
}
public static void trueThrowBusinessError(boolean flag, Supplier<String> supplier) {
if (flag) {
throw new NflgException(STATE.BusinessError, supplier.get());
}
}
public static ThrowExceptionFunction trueThrow(boolean flag) {
return (state,errorMessage) -> {

View File

@ -177,4 +177,9 @@ public class WmsComponentOutbound implements Serializable {
* 物料年度凭证
*/
private String materialDocYear;
/**
* 是否冲销
*/
private Boolean isReverse;
}

View File

@ -14,7 +14,7 @@ import java.time.LocalDateTime;
/**
* <p>
*
*
* </p>
*
* @author 代码生成器生成
@ -160,7 +160,7 @@ public class WmsComponentPacking implements Serializable {
private String factoryNo;
/**
* 0 未出库1 部分出库2 出库完成
* 0 未出库1 对冲2 出库完成
*/
private Short isCompleted;
}

View File

@ -6,7 +6,7 @@
select id,packing_no,
outbound_no,matnr,name1,uname,vbeln,maktx,datum,xnum,cnum,bname,zjshz,zchep,tel_number,sernr,huodh,vbelv,
p_name,l_bezei,l_name,g_streen,g_str_suppl2,wbstk,create_name,create_time,factory_no,create_id,
create_name,create_time,packing_id
create_name,create_time,packing_id,is_reverse
from wms_component_outbound
<where>
<if test="request.packingNo !=null and request.packingNo !=''">

View File

@ -33,7 +33,7 @@ public class CodeGeneratorTest {
)
.strategyConfig(builder -> {
builder
.addInclude("wms_inventory_barcode_printing") //只生成指定表
.addInclude("wms_component_outbound") //只生成指定表
.entityBuilder().idType(IdType.ASSIGN_ID)
.enableLombok()
.enableChainModel()