package cn.iocoder.yudao.module.asset.service.requisition; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.asset.controller.admin.requisition.vo.AssetRequisitionPageReqVO; import cn.iocoder.yudao.module.asset.controller.admin.requisition.vo.AssetRequisitionReturnReqVO; import cn.iocoder.yudao.module.asset.controller.admin.requisition.vo.AssetRequisitionSaveReqVO; import cn.iocoder.yudao.module.asset.dal.dataobject.item.AssetItemDO; import cn.iocoder.yudao.module.asset.dal.dataobject.requisition.AssetRequisitionDO; import cn.iocoder.yudao.module.asset.dal.mysql.requisition.AssetRequisitionMapper; import cn.iocoder.yudao.module.asset.dal.redis.AssetNoRedisDAO; import cn.iocoder.yudao.module.asset.enums.AssetReturnStatusEnum; import cn.iocoder.yudao.module.asset.service.item.AssetItemService; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.asset.enums.ErrorCodeConstants.*; /** * 资产领用 Service 实现类 */ @Service @Validated @Slf4j public class AssetRequisitionServiceImpl implements AssetRequisitionService { @Resource private AssetRequisitionMapper requisitionMapper; @Resource private AssetItemService itemService; @Resource private AssetNoRedisDAO noRedisDAO; @Override @Transactional(rollbackFor = Exception.class) public Long createRequisition(AssetRequisitionSaveReqVO reqVO) { AssetItemDO item = itemService.getItem(reqVO.getAssetId()); if (item == null) { throw exception(ASSET_ITEM_NOT_EXISTS); } // 先扣库存,库存不足会抛出精确提示 itemService.decreaseStock(item.getId(), reqVO.getQuantity()); AssetRequisitionDO requisition = BeanUtils.toBean(reqVO, AssetRequisitionDO.class, in -> in .setNo(noRedisDAO.generate(AssetNoRedisDAO.ASSET_REQUISITION_NO_PREFIX)) .setAssetNo(item.getAssetNo()) .setAssetName(item.getName()) .setCategory(item.getCategory()) .setCustodianId(item.getCustodianId()) .setCustodianName(item.getCustodianName()) .setReturnedQuantity(0) .setReturnStatus(AssetReturnStatusEnum.NOT_RETURNED.getStatus())); requisitionMapper.insert(requisition); return requisition.getId(); } @Override @Transactional(rollbackFor = Exception.class) public void updateRequisition(AssetRequisitionSaveReqVO reqVO) { AssetRequisitionDO old = validateRequisitionExists(reqVO.getId()); // 修改仅允许调整领用人、用途、预计归还日期与备注;资产与数量不允许直接改,避免库存账实不符 AssetRequisitionDO updateObj = new AssetRequisitionDO() .setId(old.getId()) .setRecipientId(reqVO.getRecipientId()) .setRecipientName(reqVO.getRecipientName()) .setPurpose(reqVO.getPurpose()) .setExpectedReturnDate(reqVO.getExpectedReturnDate()) .setRemark(reqVO.getRemark()); requisitionMapper.updateById(updateObj); } @Override @Transactional(rollbackFor = Exception.class) public void deleteRequisition(Long id) { AssetRequisitionDO requisition = validateRequisitionExists(id); int returned = requisition.getReturnedQuantity() == null ? 0 : requisition.getReturnedQuantity(); if (returned > 0) { throw exception(ASSET_REQUISITION_DELETE_FAIL_RETURNED); } // 冲销:把未归还数量退回库存 itemService.increaseStock(requisition.getAssetId(), requisition.getQuantity()); requisitionMapper.deleteById(id); } @Override @Transactional(rollbackFor = Exception.class) public void returnRequisition(AssetRequisitionReturnReqVO reqVO) { AssetRequisitionDO requisition = validateRequisitionExists(reqVO.getId()); int total = requisition.getQuantity() == null ? 0 : requisition.getQuantity(); int returned = requisition.getReturnedQuantity() == null ? 0 : requisition.getReturnedQuantity(); int remaining = total - returned; if (remaining <= 0) { throw exception(ASSET_REQUISITION_RETURN_COMPLETED); } if (reqVO.getReturnQuantity() == null || reqVO.getReturnQuantity() <= 0 || reqVO.getReturnQuantity() > remaining) { throw exception(ASSET_REQUISITION_RETURN_QUANTITY_INVALID, total, returned, reqVO.getReturnQuantity(), remaining); } int newReturned = returned + reqVO.getReturnQuantity(); int newStatus = newReturned >= total ? AssetReturnStatusEnum.RETURNED.getStatus() : AssetReturnStatusEnum.PARTIAL.getStatus(); requisitionMapper.updateById(new AssetRequisitionDO() .setId(requisition.getId()) .setReturnedQuantity(newReturned) .setReturnTime(reqVO.getReturnTime() != null ? reqVO.getReturnTime() : LocalDateTime.now()) .setReturnStatus(newStatus) .setRemark(StrUtil.blankToDefault(reqVO.getRemark(), requisition.getRemark()))); itemService.increaseStock(requisition.getAssetId(), reqVO.getReturnQuantity()); } @Override public AssetRequisitionDO getRequisition(Long id) { return requisitionMapper.selectById(id); } @Override public PageResult getRequisitionPage(AssetRequisitionPageReqVO reqVO) { return requisitionMapper.selectPage(reqVO); } private AssetRequisitionDO validateRequisitionExists(Long id) { AssetRequisitionDO requisition = id != null ? requisitionMapper.selectById(id) : null; if (requisition == null) { throw exception(ASSET_REQUISITION_NOT_EXISTS); } return requisition; } }