package cn.iocoder.yudao.module.purchase.service.order; import cn.hutool.core.collection.CollUtil; 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.purchase.controller.admin.order.vo.PurchaseOrderItemSaveReqVO; import cn.iocoder.yudao.module.purchase.controller.admin.order.vo.PurchaseOrderPageReqVO; import cn.iocoder.yudao.module.purchase.controller.admin.order.vo.PurchaseOrderSaveReqVO; import cn.iocoder.yudao.module.purchase.dal.dataobject.order.PurchaseOrderDO; import cn.iocoder.yudao.module.purchase.dal.dataobject.order.PurchaseOrderItemDO; import cn.iocoder.yudao.module.purchase.dal.mysql.order.PurchaseOrderLineMapper; import cn.iocoder.yudao.module.purchase.dal.mysql.order.PurchaseOrderMainMapper; import cn.iocoder.yudao.module.purchase.dal.redis.PurchaseNoRedisDAO; 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.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.purchase.enums.ErrorCodeConstants.*; /** * 采购单 Service 实现类 */ @Service @Validated @Slf4j public class PurchaseOrderServiceImpl implements PurchaseOrderService { /** 草稿状态 */ private static final Integer STATUS_DRAFT = 0; @Resource private PurchaseOrderMainMapper orderMapper; @Resource private PurchaseOrderLineMapper itemMapper; @Resource private PurchaseNoRedisDAO noRedisDAO; @Override @Transactional(rollbackFor = Exception.class) public Long createOrder(PurchaseOrderSaveReqVO reqVO) { List items = buildItems(null, reqVO.getItems()); PurchaseOrderDO order = BeanUtils.toBean(reqVO, PurchaseOrderDO.class, in -> in .setNo(noRedisDAO.generate(PurchaseNoRedisDAO.ORDER_NO_PREFIX)) .setStatus(STATUS_DRAFT) .setTotalAmount(sumAmount(items))); orderMapper.insert(order); items.forEach(item -> item.setOrderId(order.getId())); itemMapper.insertBatch(items); return order.getId(); } @Override @Transactional(rollbackFor = Exception.class) public void updateOrder(PurchaseOrderSaveReqVO reqVO) { PurchaseOrderDO old = validateOrderExists(reqVO.getId()); if (!STATUS_DRAFT.equals(old.getStatus())) { throw exception(PURCHASE_ORDER_UPDATE_FAIL, old.getNo(), "非草稿"); } List items = buildItems(reqVO.getId(), reqVO.getItems()); PurchaseOrderDO updateObj = BeanUtils.toBean(reqVO, PurchaseOrderDO.class, in -> in .setTotalAmount(sumAmount(items))); // 单号与状态不允许通过修改接口变更 updateObj.setNo(null).setStatus(null); orderMapper.updateById(updateObj); itemMapper.deleteByOrderId(reqVO.getId()); itemMapper.insertBatch(items); } @Override @Transactional(rollbackFor = Exception.class) public void deleteOrder(Long id) { PurchaseOrderDO order = validateOrderExists(id); if (!STATUS_DRAFT.equals(order.getStatus())) { throw exception(PURCHASE_ORDER_DELETE_FAIL, order.getNo(), "非草稿"); } itemMapper.deleteByOrderId(id); orderMapper.deleteById(id); } @Override public PurchaseOrderDO getOrder(Long id) { return orderMapper.selectById(id); } @Override public List getItemListByOrderId(Long orderId) { return itemMapper.selectListByOrderId(orderId); } @Override public PageResult getOrderPage(PurchaseOrderPageReqVO reqVO) { return orderMapper.selectPage(reqVO); } private PurchaseOrderDO validateOrderExists(Long id) { PurchaseOrderDO order = id != null ? orderMapper.selectById(id) : null; if (order == null) { throw exception(PURCHASE_ORDER_NOT_EXISTS); } return order; } /** 组装明细:计算每行金额与排序号 */ private List buildItems(Long orderId, List items) { if (CollUtil.isEmpty(items)) { throw exception(PURCHASE_ORDER_ITEM_EMPTY); } List result = new ArrayList<>(items.size()); int index = 1; for (PurchaseOrderItemSaveReqVO item : items) { if (item == null || StrUtil.isBlank(item.getItemName())) { throw exception(PURCHASE_ORDER_ITEM_NAME_EMPTY, index); } BigDecimal quantity = item.getQuantity() == null ? BigDecimal.ZERO : item.getQuantity(); BigDecimal unitPrice = item.getUnitPrice() == null ? BigDecimal.ZERO : item.getUnitPrice(); BigDecimal amount = quantity.multiply(unitPrice).setScale(2, RoundingMode.HALF_UP); result.add(PurchaseOrderItemDO.builder() .orderId(orderId) .itemName(StrUtil.trim(item.getItemName())) .spec(StrUtil.trim(item.getSpec())) .quantity(quantity) .unitPrice(unitPrice) .amount(amount) .sortNo(item.getSortNo() != null ? item.getSortNo() : index) .build()); index++; } return result; } private BigDecimal sumAmount(List items) { return items.stream() .map(PurchaseOrderItemDO::getAmount) .filter(java.util.Objects::nonNull) .reduce(BigDecimal.ZERO, BigDecimal::add) .setScale(2, RoundingMode.HALF_UP); } }