Parcourir la source

新增采购退货功能

fgd il y a 1 an
Parent
commit
f8bb67df5d

+ 12 - 0
sd-business/src/main/java/com/sd/business/controller/purchase/PurchaseReturnController.java

@@ -4,16 +4,19 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.fjhx.flow.enums.FlowStatusEnum;
 import com.ruoyi.common.core.domain.BaseSelectDto;
 import com.sd.business.entity.purchase.dto.PurchaseReturnDto;
+import com.sd.business.entity.purchase.dto.PurchaseReturnImportDataDto;
 import com.sd.business.entity.purchase.dto.PurchaseReturnSelectDto;
 import com.sd.business.entity.purchase.vo.PurchaseReturnBomVo;
 import com.sd.business.entity.purchase.vo.PurchaseReturnDetailVo;
 import com.sd.business.entity.purchase.vo.PurchaseReturnVo;
 import com.sd.business.service.purchase.PurchaseReturnService;
+import com.sd.framework.util.excel.util.ExcelUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.util.List;
 
@@ -72,4 +75,13 @@ public class PurchaseReturnController {
     public List<PurchaseReturnBomVo> getPurchaseBomPage(@RequestBody BaseSelectDto dto) {
         return purchaseReturnService.getPurchaseBomPage(dto.getId());
     }
+
+    /**
+     * 导入采购退货
+     */
+    @PostMapping("/purchaseReturnImport")
+    public void purchaseReturnImport(MultipartFile file) {
+        List<PurchaseReturnImportDataDto> list = ExcelUtil.read(file, PurchaseReturnImportDataDto.class);
+        purchaseReturnService.purchaseReturnImport(list);
+    }
 }

+ 36 - 0
sd-business/src/main/java/com/sd/business/entity/purchase/dto/PurchaseReturnImportDataDto.java

@@ -0,0 +1,36 @@
+package com.sd.business.entity.purchase.dto;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.math.BigDecimal;
+
+/**
+ * 采购退货导入入参实体
+ *
+ * @author
+ * @since 2023-12-19
+ */
+@Getter
+@Setter
+public class PurchaseReturnImportDataDto {
+
+    /**
+     * 采购合同编号-PUR
+     */
+    @ExcelProperty("备注")
+    private String purchaseCode;
+
+    /**
+     * bom规格编码
+     */
+    @ExcelProperty("品号")
+    private String bomSpecCode;
+
+    /**
+     * 退货数量
+     */
+    @ExcelProperty("数量")
+    private BigDecimal quantity;
+}

+ 7 - 0
sd-business/src/main/java/com/sd/business/service/purchase/PurchaseReturnService.java

@@ -3,6 +3,7 @@ package com.sd.business.service.purchase;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ruoyi.common.core.service.BaseService;
 import com.sd.business.entity.purchase.dto.PurchaseReturnDto;
+import com.sd.business.entity.purchase.dto.PurchaseReturnImportDataDto;
 import com.sd.business.entity.purchase.dto.PurchaseReturnSelectDto;
 import com.sd.business.entity.purchase.po.PurchaseReturn;
 import com.sd.business.entity.purchase.vo.PurchaseReturnBomVo;
@@ -59,4 +60,10 @@ public interface PurchaseReturnService extends BaseService<PurchaseReturn> {
      * @param id
      */
     void outPurchaseReturn(Long id);
+
+    /**
+     * 导入采购退货
+     * @param list
+     */
+    void purchaseReturnImport(List<PurchaseReturnImportDataDto> list);
 }

+ 117 - 6
sd-business/src/main/java/com/sd/business/service/purchase/impl/PurchaseReturnServiceImpl.java

@@ -3,6 +3,8 @@ package com.sd.business.service.purchase.impl;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.dynamic.datasource.annotation.DSTransactional;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fjhx.flow.enums.FlowStatusEnum;
@@ -10,6 +12,7 @@ import com.ruoyi.common.constant.StatusConstant;
 import com.ruoyi.common.core.domain.BaseIdPo;
 import com.ruoyi.common.core.domain.entity.SysUser;
 import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.wrapper.IWrapper;
 import com.ruoyi.system.service.ISysUserService;
 import com.sd.business.entity.bom.po.BomSpec;
@@ -20,7 +23,9 @@ import com.sd.business.entity.in.emums.OutDetailTypeEnum;
 import com.sd.business.entity.in.po.InOutStorageBom;
 import com.sd.business.entity.inventory.po.Inventory;
 import com.sd.business.entity.purchase.dto.PurchaseReturnDto;
+import com.sd.business.entity.purchase.dto.PurchaseReturnImportDataDto;
 import com.sd.business.entity.purchase.dto.PurchaseReturnSelectDto;
+import com.sd.business.entity.purchase.enums.PurchaseStatusEnum;
 import com.sd.business.entity.purchase.po.Purchase;
 import com.sd.business.entity.purchase.po.PurchaseBom;
 import com.sd.business.entity.purchase.po.PurchaseReturn;
@@ -39,9 +44,11 @@ import com.sd.business.util.CodeEnum;
 import com.sd.framework.util.Assert;
 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.*;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 @Service
@@ -71,6 +78,7 @@ public class PurchaseReturnServiceImpl extends ServiceImpl<PurchaseReturnMapper,
     public Page<PurchaseReturnVo> getPage(PurchaseReturnSelectDto dto) {
         IWrapper<PurchaseReturn> wrapper = getWrapper();
         wrapper.orderByDesc("pr", PurchaseReturn::getId);
+        wrapper.groupBy("pr.id");
         wrapper.eq("pr", PurchaseReturn::getFlowStatus, dto.getFlowStatus());
 
         // 查询采购退货数据
@@ -81,17 +89,12 @@ public class PurchaseReturnServiceImpl extends ServiceImpl<PurchaseReturnMapper,
             return page;
         }
         records.forEach(item -> {
-            // 采购合同数量
-            long count = purchaseReturnBomService.count(q -> q
-                    .eq(PurchaseReturnBom::getPurchaseReturnId, item.getId())
-                    .groupBy(PurchaseReturnBom::getPurchaseId));
             // 发起人
             SysUser user = userService.selectUserById(item.getCreateUser());
             // 如果采购退货通过,退货时间取最新的更新时间
             if (Objects.equals(FlowStatusEnum.PASS.getKey(), item.getFlowStatus())) {
                 item.setReturnTime(item.getUpdateTime());
             }
-            item.setPurchaseCount(count);
             item.setCreateName(user.getNickName());
         });
         return page;
@@ -123,7 +126,7 @@ public class PurchaseReturnServiceImpl extends ServiceImpl<PurchaseReturnMapper,
             }
             Inventory inventory = inventoryMap.get(item.getBomSpecId());
             if (inventory == null || inventory.getQuantity().compareTo(item.getReturnQuantity()) < 0) {
-                throw new ServiceException("退货失败,品名为:" + bomSpec.getName() + " 的bom库存不足,库存为:" +
+                throw new ServiceException("退货失败,品号为:" + bomSpec.getCode() + " 的bom库存不足,库存为:" +
                         (inventory == null ? BigDecimal.ZERO : inventory.getQuantity()));
             }
         });
@@ -287,4 +290,112 @@ public class PurchaseReturnServiceImpl extends ServiceImpl<PurchaseReturnMapper,
         list.forEach(item -> item.setReturnQuantity(item.getReturnQuantity().add(returnQuantityMap.get(item.getId()))));
         purchaseBomService.updateBatchById(list);
     }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void purchaseReturnImport(List<PurchaseReturnImportDataDto> list) {
+        this.validatedImportData(list);
+        List<String> purchaseCodes = list.stream().map(PurchaseReturnImportDataDto::getPurchaseCode).collect(Collectors.toList());
+        // 采购合同数据
+        List<Purchase> purchaseList = purchaseService.list(q -> q.in(Purchase::getCode, purchaseCodes));
+        if (purchaseList.isEmpty()) {
+            throw new ServiceException("未知采购合同订单单号");
+        }
+
+        Map<String, Purchase> purchaseMap = purchaseList.stream().collect(Collectors.toMap(Purchase::getCode, Function.identity()));
+        List<Long> purchaseIds = purchaseList.stream().map(BaseIdPo::getId).collect(Collectors.toList());
+        // 采购合同bom 数据
+        Map<Long, List<PurchaseBom>> purchaseBomMap = purchaseBomService.mapKGroup(PurchaseBom::getPurchaseId, q -> q.in(PurchaseBom::getPurchaseId, purchaseIds));
+        // bom数据
+        List<String> bomSpecCodes = list.stream().map(PurchaseReturnImportDataDto::getBomSpecCode).collect(Collectors.toList());
+        Map<String, BomSpec> bomSpecMap = bomSpecService.mapKEntity(BomSpec::getCode, q -> q.in(BomSpec::getCode, bomSpecCodes));
+
+        PurchaseReturn purchaseReturn = new PurchaseReturn();
+        purchaseReturn.setId(IdWorker.getId());
+        purchaseReturn.setCode(CodeEnum.PURCHASE_TH_CODE.getCode());
+        purchaseReturn.setFlowStatus(FlowStatusEnum.PASS.getKey());
+        purchaseReturn.setReturnAmount(BigDecimal.ZERO);
+        List<PurchaseReturnBom> purchaseReturnBomList = new ArrayList<>();
+        // 退货采购bom
+        Map<Long, PurchaseBom> returnPurchaseBomMap = new HashMap<>();
+
+        for (PurchaseReturnImportDataDto dto : list) {
+            Purchase purchase = purchaseMap.get(dto.getPurchaseCode());
+            if (purchase == null) {
+                throw new ServiceException("未知采购合同订单单号:" + dto.getPurchaseCode());
+            } else if (!(Objects.equals(purchase.getStatus(), PurchaseStatusEnum.UNDER_PURCHASE.getKey())
+                    || Objects.equals(purchase.getStatus(), PurchaseStatusEnum.HAVE_PURCHASE.getKey()))) {
+                throw new ServiceException("采购合同:" + dto.getPurchaseCode() + "错误,请选择采购中和已采购的合同");
+            }
+            // 判断采购合同是否存在当前bom
+            BomSpec bomSpec = bomSpecMap.get(dto.getBomSpecCode());
+            if (bomSpec == null) {
+                throw new ServiceException("未知bom品号:" + dto.getBomSpecCode());
+            }
+            List<PurchaseBom> purchaseBomList = purchaseBomMap.get(purchase.getId());
+            PurchaseBom purchaseBom = purchaseBomList.stream().filter(item -> ObjectUtil.equals(bomSpec.getId(), item.getBomSpecId())).findFirst().orElse(null);
+            if (purchaseBom == null) {
+                throw new ServiceException("采购合同" + dto.getPurchaseCode() + "清单中不存在bom品号:" + dto.getPurchaseCode());
+            }
+            // 判断到货数量是否超出采购可入库数量
+            BigDecimal canReturnQuantity = purchaseBom.getArrivalQuantity().subtract(purchaseBom.getReturnQuantity());
+            if (canReturnQuantity.compareTo(dto.getQuantity()) < 0) {
+                throw new ServiceException("bom品号:" + dto.getBomSpecCode() + "超出可退货数量");
+            }
+
+            // 新增退货数据
+            PurchaseReturnBom purchaseReturnBom = new PurchaseReturnBom();
+            purchaseReturnBom.setPurchaseReturnId(purchaseReturn.getId());
+            purchaseReturnBom.setPurchaseId(purchase.getId());
+            purchaseReturnBom.setPurchaseBomId(purchaseBom.getId());
+            purchaseReturnBom.setBomSpecId(bomSpec.getId());
+            purchaseReturnBom.setReturnQuantity(dto.getQuantity());
+            purchaseReturnBomList.add(purchaseReturnBom);
+            purchaseReturn.setReturnAmount(purchaseReturn.getReturnAmount()
+                    .add(purchaseBom.getUnitPrice().multiply(purchaseReturnBom.getReturnQuantity())));
+
+            // 保存退货采购bom
+            purchaseBom.setReturnQuantity(purchaseBom.getReturnQuantity().add(dto.getQuantity()));
+            returnPurchaseBomMap.putIfAbsent(purchaseBom.getId(), purchaseBom);
+        }
+
+        // 新增出库信息
+        List<InOutStorageBom> inOutStorageBomList = purchaseReturnBomList.stream().map(item -> {
+            InOutStorageBom inOutStorageBom = new InOutStorageBom();
+            inOutStorageBom.setBomSpecId(item.getBomSpecId());
+            inOutStorageBom.setQuantity(item.getReturnQuantity());
+            return inOutStorageBom;
+        }).collect(Collectors.toList());
+
+        InOutStorageDto inOutStorageDto = new InOutStorageDto();
+        inOutStorageDto.setType(InOutTypeEnum.OUT.getKey());
+        inOutStorageDto.setDetailType(OutDetailTypeEnum.PURCHASE.getKey());
+        inOutStorageDto.setWarehouseId(WarehouseConstant.PURCHASE_DEFECTIVE);
+        inOutStorageDto.setDepartmentId(DepartmentConstant.SD_SPORTS);
+        inOutStorageDto.setApplicant(SecurityUtils.getLoginUser().getUser().getNickName());
+        inOutStorageDto.setLockStorage(StatusConstant.NO);
+        inOutStorageDto.setInOutStorageBomList(inOutStorageBomList);
+        inOutStorageService.add(inOutStorageDto);
+
+        // 更新采购合同数据
+        purchaseService.update(q -> q
+                .set(Purchase::getStatus, PurchaseStatusEnum.UNDER_PURCHASE.getKey())
+                .set(Purchase::getStorageStatus, StatusConstant.NO)
+                .in(BaseIdPo::getId, purchaseIds)
+                .eq(Purchase::getStatus, PurchaseStatusEnum.HAVE_PURCHASE.getKey()));
+        purchaseBomService.updateBatchById(returnPurchaseBomMap.values());
+
+        // 保存采购退货数据
+        this.save(purchaseReturn);
+        purchaseReturnBomService.saveBatch(purchaseReturnBomList);
+    }
+
+    private void validatedImportData(List<PurchaseReturnImportDataDto> list) {
+        Assert.notEmpty(list, "退货明细不能为空");
+        for (PurchaseReturnImportDataDto dto : list) {
+            Assert.notBlank(dto.getPurchaseCode(), "采购订单单号不能为空");
+            Assert.notBlank(dto.getBomSpecCode(), "bom品号不能为空");
+            Assert.gtZero(dto.getQuantity(), "数量必须大于0");
+        }
+    }
 }

+ 5 - 0
sd-business/src/main/java/com/sd/business/service/sku/impl/SkuServiceImpl.java

@@ -237,10 +237,15 @@ public class SkuServiceImpl extends ServiceImpl<SkuMapper, Sku> implements SkuSe
 
         List<Long> skuSpecIdList = baseMapper.selectReplaceSkuSpecIdList(wrapper);
 
+        BomSpec bomSpec = bomSpecService.getById(dto.getReplaceBomSpecId());
+
         List<SkuSpec> skuSpecList = skuSpecIdList.stream().map(item -> {
             SkuSpec skuSpec = new SkuSpec();
             skuSpec.setId(item);
             skuSpec.setBomSpecId(dto.getReplaceBomSpecId());
+            skuSpec.setLength(bomSpec.getLength());
+            skuSpec.setWidth(bomSpec.getWidth());
+            skuSpec.setHeight(bomSpec.getHeight());
             return skuSpec;
         }).collect(Collectors.toList());
 

+ 3 - 1
sd-business/src/main/resources/mapper/purchase/PurchaseReturnMapper.xml

@@ -12,8 +12,10 @@
             pr.create_user,
             pr.create_time,
             pr.update_user,
-            pr.update_time
+            pr.update_time,
+            count(DISTINCT prb.purchase_id) purchaseCount
         from purchase_return pr
+                 inner join purchase_return_bom prb on pr.id = prb.purchase_return_id
             ${ew.customSqlSegment}
     </select>