|
@@ -0,0 +1,277 @@
|
|
|
+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.extension.plugins.pagination.Page;
|
|
|
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import com.fjhx.flow.enums.FlowStatusEnum;
|
|
|
+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.wrapper.IWrapper;
|
|
|
+import com.ruoyi.system.service.ISysUserService;
|
|
|
+import com.sd.business.entity.bom.po.BomSpec;
|
|
|
+import com.sd.business.entity.department.constant.DepartmentConstant;
|
|
|
+import com.sd.business.entity.in.dto.InOutStorageDto;
|
|
|
+import com.sd.business.entity.in.emums.InOutTypeEnum;
|
|
|
+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.PurchaseReturnSelectDto;
|
|
|
+import com.sd.business.entity.purchase.po.Purchase;
|
|
|
+import com.sd.business.entity.purchase.po.PurchaseBom;
|
|
|
+import com.sd.business.entity.purchase.po.PurchaseReturn;
|
|
|
+import com.sd.business.entity.purchase.po.PurchaseReturnBom;
|
|
|
+import com.sd.business.entity.purchase.vo.*;
|
|
|
+import com.sd.business.entity.warehouse.constant.WarehouseConstant;
|
|
|
+import com.sd.business.mapper.purchase.PurchaseReturnMapper;
|
|
|
+import com.sd.business.service.bom.BomSpecService;
|
|
|
+import com.sd.business.service.in.InOutStorageService;
|
|
|
+import com.sd.business.service.inventory.InventoryService;
|
|
|
+import com.sd.business.service.purchase.PurchaseBomService;
|
|
|
+import com.sd.business.service.purchase.PurchaseReturnBomService;
|
|
|
+import com.sd.business.service.purchase.PurchaseReturnService;
|
|
|
+import com.sd.business.service.purchase.PurchaseService;
|
|
|
+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 java.math.BigDecimal;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+@Service
|
|
|
+public class PurchaseReturnServiceImpl extends ServiceImpl<PurchaseReturnMapper, PurchaseReturn> implements PurchaseReturnService {
|
|
|
+ @Autowired
|
|
|
+ private ISysUserService userService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private PurchaseReturnBomService purchaseReturnBomService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private InventoryService inventoryService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private BomSpecService bomSpecService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private PurchaseService purchaseService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private PurchaseBomService purchaseBomService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private InOutStorageService inOutStorageService;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Page<PurchaseReturnVo> getPage(PurchaseReturnSelectDto dto) {
|
|
|
+ IWrapper<PurchaseReturn> wrapper = getWrapper();
|
|
|
+ wrapper.orderByDesc("pr", PurchaseReturn::getId);
|
|
|
+
|
|
|
+ // 查询采购退货数据
|
|
|
+ Page<PurchaseReturnVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
|
|
|
+
|
|
|
+ List<PurchaseReturnVo> records = page.getRecords();
|
|
|
+ if (records.size() == 0) {
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+
|
|
|
+ @DSTransactional
|
|
|
+ @Override
|
|
|
+ public void add(PurchaseReturnDto purchaseReturnDto) {
|
|
|
+ // 保存采购退货
|
|
|
+ purchaseReturnDto.setCode(CodeEnum.PURCHASE_TH_CODE.getCode());
|
|
|
+ this.save(purchaseReturnDto);
|
|
|
+
|
|
|
+ List<PurchaseReturnBom> purchaseReturnBomList = purchaseReturnDto.getPurchaseReturnBomList();
|
|
|
+ // bom id
|
|
|
+ List<Long> bomSpecIds = purchaseReturnBomList.stream().map(PurchaseReturnBom::getBomSpecId).collect(Collectors.toList());
|
|
|
+ Assert.notEmpty(bomSpecIds, "采购bom列表不能为空");
|
|
|
+ // bom库存
|
|
|
+ Map<Long, Inventory> inventoryMap = inventoryService.mapKEntity(Inventory::getBomSpecId,
|
|
|
+ q -> q.eq(Inventory::getWarehouseId, WarehouseConstant.PURCHASE_DEFECTIVE)
|
|
|
+ .eq(Inventory::getDepartmentId, DepartmentConstant.SD_SPORTS)
|
|
|
+ .in(Inventory::getBomSpecId, bomSpecIds));
|
|
|
+ // bom规格信息
|
|
|
+ Map<Long, BomSpec> bomSpecMap = bomSpecService.mapKEntity(BaseIdPo::getId, q -> q.in(BaseIdPo::getId, bomSpecIds));
|
|
|
+ purchaseReturnBomList.forEach(item -> {
|
|
|
+ item.setPurchaseReturnId(purchaseReturnDto.getId());
|
|
|
+ BomSpec bomSpec = bomSpecMap.get(item.getPurchaseBomId());
|
|
|
+ if (bomSpec == null) {
|
|
|
+ throw new ServiceException("未知bom规格id!");
|
|
|
+ }
|
|
|
+ Inventory inventory = inventoryMap.get(item.getPurchaseBomId());
|
|
|
+ if (inventory == null || inventory.getQuantity().compareTo(item.getReturnQuantity()) < 0) {
|
|
|
+ throw new ServiceException("退货失败,品名为:" + bomSpec.getName() + " 的bom库存不足,库存为:" +
|
|
|
+ (inventory == null ? BigDecimal.ZERO : inventory.getQuantity()));
|
|
|
+ }
|
|
|
+ });
|
|
|
+ Map<Long, BigDecimal> map = purchaseReturnBomList.stream()
|
|
|
+ .collect(Collectors.toMap(
|
|
|
+ PurchaseReturnBom::getBomSpecId,
|
|
|
+ PurchaseReturnBom::getReturnQuantity,
|
|
|
+ BigDecimal::add
|
|
|
+ ));
|
|
|
+
|
|
|
+ boolean result = inventoryService.lockPurchaseDefectiveStorage(map);
|
|
|
+ if (!result) {
|
|
|
+ throw new ServiceException("库存不足,退货失败");
|
|
|
+ }
|
|
|
+ purchaseReturnBomService.saveBatch(purchaseReturnBomList);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void edit(PurchaseReturnDto purchaseReturnDto) {
|
|
|
+ // 状态为未发起时, 流程重新发起
|
|
|
+ if (ObjectUtil.equals(purchaseReturnDto.getFlowStatus(), FlowStatusEnum.READY_START.getKey())) {
|
|
|
+ purchaseReturnDto.setFlowStatus(FlowStatusEnum.IN_PROGRESS.getKey());
|
|
|
+ }
|
|
|
+ // 保存采购退货
|
|
|
+ this.updateById(purchaseReturnDto);
|
|
|
+
|
|
|
+ List<PurchaseReturnBom> newPurchaseReturnBomList = purchaseReturnDto.getPurchaseReturnBomList();
|
|
|
+ Assert.notEmpty(newPurchaseReturnBomList, "采购bom列表不能为空");
|
|
|
+ List<PurchaseReturnBom> oldPurchaseReturnBomList = purchaseReturnBomService.list(q -> q
|
|
|
+ .eq(PurchaseReturnBom::getPurchaseReturnId, purchaseReturnDto.getId()));
|
|
|
+
|
|
|
+ // 旧采购bom
|
|
|
+ Map<Long, BigDecimal> oldBomMap = oldPurchaseReturnBomList.stream()
|
|
|
+ .collect(Collectors.toMap(
|
|
|
+ PurchaseReturnBom::getBomSpecId,
|
|
|
+ PurchaseReturnBom::getReturnQuantity,
|
|
|
+ BigDecimal::add
|
|
|
+ ));
|
|
|
+ Map<Long, BigDecimal> newBomMap = newPurchaseReturnBomList.stream()
|
|
|
+ .collect(Collectors.toMap(
|
|
|
+ PurchaseReturnBom::getBomSpecId,
|
|
|
+ PurchaseReturnBom::getReturnQuantity,
|
|
|
+ BigDecimal::add
|
|
|
+ ));
|
|
|
+ // 查询所有bom进行对比
|
|
|
+ Set<Long> bomIds = new HashSet<>(oldBomMap.keySet());
|
|
|
+ bomIds.addAll(newBomMap.keySet());
|
|
|
+ Map<Long, BigDecimal> lockBomMap = new HashMap<>();
|
|
|
+ Map<Long, BigDecimal> unlockBomMap = new HashMap<>();
|
|
|
+ for (Long bomId : bomIds) {
|
|
|
+ BigDecimal oldReturnQuantity = oldBomMap.get(bomId);
|
|
|
+ BigDecimal newReturnQuantity = newBomMap.get(bomId);
|
|
|
+ // 旧bom没有,新增锁定库存,反之则解锁库存
|
|
|
+ if (oldReturnQuantity == null) {
|
|
|
+ lockBomMap.put(bomId, newReturnQuantity);
|
|
|
+ continue;
|
|
|
+ } else if (newReturnQuantity == null) {
|
|
|
+ unlockBomMap.put(bomId, oldReturnQuantity);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // 都有值,判断数量
|
|
|
+ if (oldReturnQuantity.compareTo(newReturnQuantity) == 0) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // 旧bom大于新bom则解锁,反之加锁库存
|
|
|
+ if (oldReturnQuantity.compareTo(newReturnQuantity) > 0) {
|
|
|
+ unlockBomMap.put(bomId, oldReturnQuantity.subtract(newReturnQuantity));
|
|
|
+ } else {
|
|
|
+ lockBomMap.put(bomId, newReturnQuantity.subtract(oldReturnQuantity));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 对原数据有修改时,更新数据
|
|
|
+ if (!lockBomMap.isEmpty() || !unlockBomMap.isEmpty()) {
|
|
|
+ if (!lockBomMap.isEmpty()) {
|
|
|
+ boolean result = inventoryService.lockPurchaseDefectiveStorage(lockBomMap);
|
|
|
+ if (!result) {
|
|
|
+ throw new ServiceException("库存不足,新增退货失败");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!unlockBomMap.isEmpty()) {
|
|
|
+ inventoryService.unlockPurchaseDefectiveStorage(unlockBomMap);
|
|
|
+ }
|
|
|
+ purchaseReturnBomService.editLinked(newPurchaseReturnBomList, PurchaseReturnBom::getPurchaseReturnId, purchaseReturnDto.getId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public PurchaseReturnDetailVo detail(Long id) {
|
|
|
+ PurchaseReturn purchaseReturn = this.getById(id);
|
|
|
+ PurchaseReturnDetailVo result = BeanUtil.toBean(purchaseReturn, PurchaseReturnDetailVo.class);
|
|
|
+ // 查询bom列表
|
|
|
+ List<PurchaseReturnBomVo> purchaseReturnBomList = purchaseReturnBomService.selectListByPurchaseReturnId(purchaseReturn.getId());
|
|
|
+ result.setReturnBomList(purchaseReturnBomList);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<PurchaseReturnBomVo> getPurchaseBomPage(Long purchaseId) {
|
|
|
+ Purchase purchase = purchaseService.getById(purchaseId);
|
|
|
+ if (purchase == null) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+ List<PurchaseBom> list = purchaseBomService.list(q -> q.eq(PurchaseBom::getPurchaseId, purchaseId));
|
|
|
+ if (list.isEmpty()) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+ List<Long> bomIds = list.stream().map(PurchaseBom::getBomSpecId).collect(Collectors.toList());
|
|
|
+ Map<Long, BomSpec> bomSpecMap = bomSpecService.mapKEntity(BaseIdPo::getId, q -> q.in(BaseIdPo::getId, bomIds));
|
|
|
+ List<PurchaseReturnBomVo> purchaseBomList = list.stream().map(item -> {
|
|
|
+ BomSpec bomSpec = bomSpecMap.get(item.getBomSpecId());
|
|
|
+ PurchaseReturnBomVo vo = new PurchaseReturnBomVo();
|
|
|
+ vo.setBomSpecId(bomSpec.getId());
|
|
|
+ vo.setPurchaseBomId(item.getId());
|
|
|
+ vo.setPurchaseId(purchaseId);
|
|
|
+ vo.setPurchaseCode(purchase.getCode());
|
|
|
+ vo.setBomSpecCode(bomSpec.getCode());
|
|
|
+ vo.setBomSpecName(bomSpec.getName());
|
|
|
+ vo.setUnitPrice(item.getUnitPrice());
|
|
|
+ vo.setPurchaseQuantity(item.getPurchaseQuantity());
|
|
|
+ vo.setArrivalQuantity(item.getArrivalQuantity());
|
|
|
+ vo.setFinishReturnQuantity(item.getReturnQuantity());
|
|
|
+ return vo;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ return purchaseBomList;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void outPurchaseReturn(Long id) {
|
|
|
+ PurchaseReturn purchaseReturn = this.getById(id);
|
|
|
+
|
|
|
+ List<PurchaseReturnBom> purchaseReturnBomList = purchaseReturnBomService.list(q -> q.eq(PurchaseReturnBom::getPurchaseReturnId, id));
|
|
|
+ // 出库信息
|
|
|
+ List<InOutStorageBom> inOutStorageBomList = purchaseReturnBomList.stream().map(item -> {
|
|
|
+ InOutStorageBom inOutStorageBom = new InOutStorageBom();
|
|
|
+ inOutStorageBom.setBomSpecId(item.getBomSpecId());
|
|
|
+ inOutStorageBom.setQuantity(item.getReturnQuantity());
|
|
|
+ return inOutStorageBom;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ // 查询创建人
|
|
|
+ SysUser user = userService.selectUserById(purchaseReturn.getCreateUser());
|
|
|
+ InOutStorageDto lockPurchaseDefective = new InOutStorageDto();
|
|
|
+ lockPurchaseDefective.setType(InOutTypeEnum.OUT.getKey());
|
|
|
+ lockPurchaseDefective.setDetailType(OutDetailTypeEnum.PURCHASE.getKey());
|
|
|
+ lockPurchaseDefective.setWarehouseId(WarehouseConstant.PURCHASE_DEFECTIVE);
|
|
|
+ lockPurchaseDefective.setDepartmentId(DepartmentConstant.SD_SPORTS);
|
|
|
+ lockPurchaseDefective.setApplicant(user.getNickName());
|
|
|
+ lockPurchaseDefective.setRemark(purchaseReturn.getRemark());
|
|
|
+ lockPurchaseDefective.setLockStorage(StatusConstant.YES);
|
|
|
+ lockPurchaseDefective.setInOutStorageBomList(inOutStorageBomList);
|
|
|
+ inOutStorageService.add(lockPurchaseDefective);
|
|
|
+ }
|
|
|
+}
|