批量收货

main
HUOJIN\92525 2025-03-31 17:25:36 +08:00
parent f24d64d601
commit 33029502c7
6 changed files with 215 additions and 16 deletions

View File

@ -0,0 +1,26 @@
package net.lab1024.sa.admin.module.business.receive;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.domain.ValidateList;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Tag(name = "收货")
public class ReceiveController {
@Resource
private ReceiveService receiveService;
@Operation(summary = "批量收货 @author 霍锦")
@PostMapping("/receive/batchReceive")
@SaCheckPermission("receive:batchReceive")
public ResponseDTO<String> batchReceive(@RequestBody ValidateList<Long> idList) {
return receiveService.batchReceive(idList);
}
}

View File

@ -0,0 +1,109 @@
package net.lab1024.sa.admin.module.business.receive;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.annotation.Resource;
import net.lab1024.sa.admin.module.business.base.item.domain.entity.ItemEntity;
import net.lab1024.sa.admin.module.business.base.item.service.ItemQueryService;
import net.lab1024.sa.admin.module.business.receive.asnDetail.domain.entity.AsnDetailEntity;
import net.lab1024.sa.admin.module.business.receive.asnDetail.domain.vo.AsnDetailVO;
import net.lab1024.sa.admin.module.business.receive.asnDetail.manager.AsnDetailManager;
import net.lab1024.sa.admin.module.business.receive.asnDetail.service.AsnDetailQueryService;
import net.lab1024.sa.admin.module.business.receive.asnDetail.service.AsnDetailService;
import net.lab1024.sa.admin.util.JoinerResult;
import net.lab1024.sa.admin.util.ResponseDTOUtils;
import net.lab1024.sa.base.common.code.UserErrorCode;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartBigDecimalUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.*;
@Service
public class ReceiveService {
@Resource
private AsnDetailManager asnDetailManager;
@Resource
private ItemQueryService itemQueryService;
@Resource
private AsnDetailService asnDetailService;
@Resource
private AsnDetailQueryService asnDetailQueryService;
/**
*
*
* @param idList id
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> batchReceive(List<Long> idList) {
if (CollectionUtils.isEmpty(idList)) {
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
}
List<AsnDetailEntity> asnDetails = asnDetailQueryService.queryAsnDetailList(idList);
if (CollectionUtils.isEmpty(asnDetails)) {
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
}
return batchReceive(asnDetails, null);
}
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> batchReceive(List<AsnDetailEntity> asnDetails, Long locationId) {
//消息提示
JoinerResult joiner = JoinerResult.createJoiner();
//查询物料
List<Long> itemIds = asnDetails.stream().map(AsnDetailEntity::getItemId).distinct().toList();
Map<Long, ItemEntity> itemMap = itemQueryService.queryItemList(itemIds);
List<AsnDetailEntity> updateToAsnDetail = new ArrayList<>();
Set<Long> asnIds = new HashSet<>();
for (AsnDetailEntity asnDetail : asnDetails) {
ItemEntity item = itemMap.get(asnDetail.getItemId());
if (SmartBigDecimalUtil.subtract(asnDetail.getOrderQuantity(), asnDetail.getReceivedQuantity(), 2).compareTo(BigDecimal.ZERO) == 0) {
joiner.getErrorMsg().add(item.getItemCode() + "明细已收货");
continue;
}
if (asnDetail.getReceivedQuantity().compareTo(asnDetail.getOrderQuantity()) > 0) {
joiner.getErrorMsg().add(item.getItemCode() + "收货数量不能大于订单数量");
continue;
}
if (locationId == null || locationId <= 0) {
//默认库位
locationId = 1L;
}
//更新入库明细
asnDetail.setReceivedQuantity(SmartBigDecimalUtil.subtract(asnDetail.getOrderQuantity(), asnDetail.getReceivedQuantity(), 2));
updateToAsnDetail.add(asnDetail);
joiner.getSussMsg().add(item.getItemCode() + "收货成功");
asnIds.add(asnDetail.getAsnId());
}
//生成itemKey
//生成入库记录
//生成库存
//批量更新入库明细
if (CollectionUtils.isNotEmpty(updateToAsnDetail)) {
asnDetailManager.updateBatchById(updateToAsnDetail);
}
//更新入库单
asnIds.forEach(asnDetailService::refreshAsn);
return ResponseDTOUtils.buildResponseDTO(joiner);
}
}

View File

@ -7,7 +7,11 @@ import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
*
@ -18,6 +22,9 @@ import lombok.Data;
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@TableName("t_asn_detail")
public class AsnDetailEntity {

View File

@ -5,7 +5,10 @@ import io.swagger.v3.oas.annotations.media.Schema;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* VO
@ -16,6 +19,9 @@ import lombok.Data;
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class AsnDetailVO {

View File

@ -4,14 +4,19 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource;
import net.lab1024.sa.admin.module.business.base.address.domain.entity.AddressEntity;
import net.lab1024.sa.admin.module.business.base.area.domain.entity.AreaEntity;
import net.lab1024.sa.admin.module.business.base.customer.domain.entity.CustomerEntity;
import net.lab1024.sa.admin.module.business.base.item.domain.entity.ItemEntity;
import net.lab1024.sa.admin.module.business.base.item.manager.ItemManager;
import net.lab1024.sa.admin.module.business.base.item.service.ItemQueryService;
import net.lab1024.sa.admin.module.business.base.location.domain.entity.LocationEntity;
import net.lab1024.sa.admin.module.business.base.location.domain.vo.LocationVO;
import net.lab1024.sa.admin.module.business.receive.asn.domain.vo.AsnVO;
import net.lab1024.sa.admin.module.business.receive.asnDetail.dao.AsnDetailDao;
import net.lab1024.sa.admin.module.business.receive.asnDetail.domain.entity.AsnDetailEntity;
import net.lab1024.sa.admin.module.business.receive.asnDetail.domain.form.AsnDetailQueryForm;
import net.lab1024.sa.admin.module.business.receive.asnDetail.domain.vo.AsnDetailVO;
import net.lab1024.sa.admin.module.business.receive.asnDetail.manager.AsnDetailManager;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.util.SmartPageUtil;
import org.springframework.stereotype.Service;
@ -26,6 +31,9 @@ public class AsnDetailQueryService {
@Resource
private AsnDetailDao asnDetailDao;
@Resource
private ItemManager itemManager;
@Resource
private ItemQueryService itemQueryService;
@ -63,4 +71,16 @@ public class AsnDetailQueryService {
queryWrapper.eq(AsnDetailEntity::getAsnId, asnId);
return asnDetailDao.selectList(queryWrapper);
}
/**
* ids
*
* @param idList
* @return List<AsnDetailEntity>
*/
public List<AsnDetailEntity> queryAsnDetailList(List<Long> idList) {
LambdaQueryWrapper<AsnDetailEntity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(AsnDetailEntity::getAsnDetailId, idList);
return asnDetailDao.selectList(queryWrapper);
}
}

View File

@ -1,10 +1,12 @@
package net.lab1024.sa.admin.module.business.receive.asnDetail.service;
import java.math.BigDecimal;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
import net.lab1024.sa.admin.module.business.base.item.dao.ItemDao;
import net.lab1024.sa.admin.module.business.base.item.domain.entity.ItemEntity;
import net.lab1024.sa.admin.module.business.base.item.service.ItemQueryService;
import net.lab1024.sa.admin.module.business.base.item.service.ItemService;
import net.lab1024.sa.admin.module.business.receive.asn.constant.AsnOrderStatusEnum;
import net.lab1024.sa.admin.module.business.receive.asn.dao.AsnDao;
import net.lab1024.sa.admin.module.business.receive.asn.domain.entity.AsnEntity;
@ -13,6 +15,8 @@ import net.lab1024.sa.admin.module.business.receive.asnDetail.domain.entity.AsnD
import net.lab1024.sa.admin.module.business.receive.asnDetail.domain.form.AsnDetailAddForm;
import net.lab1024.sa.admin.module.business.receive.asnDetail.domain.form.AsnDetailUpdateForm;
import net.lab1024.sa.admin.module.business.receive.asnDetail.manager.AsnDetailManager;
import net.lab1024.sa.admin.util.JoinerResult;
import net.lab1024.sa.admin.util.ResponseDTOUtils;
import net.lab1024.sa.base.common.code.UserErrorCode;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.common.domain.ResponseDTO;
@ -37,12 +41,18 @@ public class AsnDetailService {
@Resource
private AsnDao asnDao;
@Resource
private ItemDao itemDao;
@Resource
private AsnDetailDao asnDetailDao;
@Resource
private AsnDetailManager asnDetailManager;
@Resource
private ItemQueryService itemQueryService;
@Resource
private AsnDetailQueryService asnDetailQueryService;
@ -83,24 +93,38 @@ public class AsnDetailService {
* @param idList id
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> batchDelete(List<Long> idList) {
if (CollectionUtils.isEmpty(idList)) {
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
}
JoinerResult joiner = JoinerResult.createJoiner();
Set<Long> asnIds = new HashSet<>();
for (Long id : idList) {
AsnDetailEntity asnDetail = asnDetailDao.selectById(id);
asnIds.add(asnDetail.getAsnId());
List<Long> toDeleteList = new ArrayList<>();
List<AsnDetailEntity> asnDetails = asnDetailQueryService.queryAsnDetailList(idList);
List<Long> itemIds = asnDetails.stream().map(AsnDetailEntity::getItemId).toList();
Map<Long, ItemEntity> mapItem = itemQueryService.queryItemList(itemIds);
for (AsnDetailEntity asnDetail : asnDetails) {
ItemEntity item = mapItem.get(asnDetail.getItemId());
if (asnDetail.getReceivedQuantity().compareTo(BigDecimal.ZERO) > 0) {
joiner.getErrorMsg().add(item.getItemCode() + "明细已收货");
continue;
}
toDeleteList.add(asnDetail.getAsnDetailId());
asnIds.add(asnDetail.getAsnId());
joiner.getSussMsg().add(item.getItemCode() + "明细删除成功");
}
if (CollectionUtils.isNotEmpty(toDeleteList)) {
//批量删除
asnDetailManager.removeBatchByIds(toDeleteList);
}
asnDetailManager.removeBatchByIds(idList);
//刷新出库单
if (CollectionUtils.isNotEmpty(asnIds)) {
for (Long asnId : asnIds) {
refreshAsn(asnId);
}
}
return ResponseDTO.ok();
asnIds.forEach(this::refreshAsn);
return ResponseDTOUtils.buildResponseDTO(joiner);
}
/**
@ -109,17 +133,27 @@ public class AsnDetailService {
* @param asnDetailId id
* @return ResponseDTO<String>
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> delete(Long asnDetailId) {
if (null == asnDetailId) {
return ResponseDTO.userErrorParam(UserErrorCode.PARAM_ERROR.getMsg());
}
JoinerResult joiner = JoinerResult.createJoiner();
AsnDetailEntity asnDetail = asnDetailDao.selectById(asnDetailId);
ItemEntity item = itemDao.selectById(asnDetail.getItemId());
if (asnDetail.getReceivedQuantity().compareTo(BigDecimal.ZERO) > 0) {
joiner.getErrorMsg().add(item.getItemCode() + "明细已收货");
return ResponseDTOUtils.buildResponseDTO(joiner);
}
Long asnId = asnDetail.getAsnId();
asnDetailDao.deleteById(asnDetailId);
joiner.getSussMsg().add(item.getItemCode() + "删除成功");
//刷新出库单
refreshAsn(asnId);
return ResponseDTO.ok();
return ResponseDTOUtils.buildResponseDTO(joiner);
}
public void refreshAsn(Long asnId) {
@ -128,9 +162,6 @@ public class AsnDetailService {
//获取订单明细
List<AsnDetailEntity> asnDetails = asnDetailQueryService.queryByAsnId(asnId);
if (CollectionUtils.isEmpty(asnDetails)) {
return;
}
//订单数量
BigDecimal orderQuantity = asnDetails.stream().map(AsnDetailEntity::getOrderQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);