liu
13 小时以前 5d34bdd3c426bb2ca5f6627424ae67984f745603
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
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<PurchaseOrderItemDO> 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<PurchaseOrderItemDO> 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<PurchaseOrderItemDO> getItemListByOrderId(Long orderId) {
        return itemMapper.selectListByOrderId(orderId);
    }
 
    @Override
    public PageResult<PurchaseOrderDO> 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<PurchaseOrderItemDO> buildItems(Long orderId, List<PurchaseOrderItemSaveReqVO> items) {
        if (CollUtil.isEmpty(items)) {
            throw exception(PURCHASE_ORDER_ITEM_EMPTY);
        }
        List<PurchaseOrderItemDO> 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<PurchaseOrderItemDO> items) {
        return items.stream()
                .map(PurchaseOrderItemDO::getAmount)
                .filter(java.util.Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .setScale(2, RoundingMode.HALF_UP);
    }
 
}