李林
2023-10-07 658d4927d468c47208fd012d9128b09249c07eff
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
/*
 *    Copyright (c) 2018-2025, ztt All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: ztt
 */
package com.chinaztt.mes.warehouse.service.impl;
 
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
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.chinaztt.mes.warehouse.dto.PrepareDetailDTO;
import com.chinaztt.mes.warehouse.dto.ReserveMainDTO;
import com.chinaztt.mes.warehouse.entity.*;
import com.chinaztt.mes.warehouse.mapper.*;
import com.chinaztt.mes.warehouse.service.PrepareDetailService;
import com.chinaztt.mes.warehouse.util.StockUtils;
import com.chinaztt.ztt.common.core.util.R;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
 
/**
 * 备料明细表
 *
 * @author sunxl
 * @date 2020-10-16 09:44:10
 */
@AllArgsConstructor
@Transactional(rollbackFor = Exception.class)
@Service
public class PrepareDetailServiceImpl extends ServiceImpl<PrepareDetailMapper, PrepareDetail> implements PrepareDetailService {
    private ReserveDetailMapper reserveDetailMapper;
    private StockMapper stockMapper;
    private StockUtils stockUtils;
    private PrepareDetailMapper prepareDetailMapper;
    private ReserveMainMapper reserveMainMapper;
    private StockInCodeMapper stockInCodeMapper;
 
    @Override
    public boolean fullDelete(Long id) {
        //将删除的数据先拿出来
        PrepareDetail prepareDetail = baseMapper.selectById(id);
        //获取对应实时库存的数据
        Stock stock = stockMapper.selectOne(Wrappers.<Stock>lambdaQuery().eq(Stock::getPartId, prepareDetail.getPartId())
                .eq(Stock::getLocationId, prepareDetail.getLocationId()).eq(Stock::getPartBatchNo, prepareDetail.getPartBatchNo()).eq(Stock::getSystemNo,prepareDetail.getSystemNo()));
        //关于id删除
        baseMapper.deleteById(id);
        //从数据库取出与这个备料关联的申请零件明细的数据
        ReserveDetail reserveDetail = reserveDetailMapper.selectOne(Wrappers.<ReserveDetail>lambdaQuery()
                .eq(ReserveDetail::getId, prepareDetail.getWarehouseReserveDetailId()).eq(ReserveDetail::getPartId, prepareDetail.getPartId()));
        //将删除的备料数量减掉
        reserveDetail.setPpoQty(reserveDetail.getPpoQty().subtract(prepareDetail.getPrepareQty()));
        if (reserveDetail.getPpoQty().compareTo(BigDecimal.ZERO) == 0) {
            reserveDetail.setStatus("已下发");
        }
        reserveDetailMapper.updateById(reserveDetail);
        ReserveMain reserveMain = reserveMainMapper.selectById(reserveDetail.getWarehouseMainId());
        StockInCode stockInCode = stockInCodeMapper.selectById(reserveMain.getResType());
        stockUtils.updateById(stock.getId(), BigDecimal.ZERO, prepareDetail.getPrepareQty().negate(), BigDecimal.ZERO, BigDecimal.ZERO, reserveMain.getResNo(), stockInCode.getStockCodeName());
        return true;
    }
 
    @Override
    public boolean fullUpdate(PrepareDetail prepareDetail) {
        //获取旧的备料数据
        PrepareDetail prepareDetailOld = baseMapper.selectOne(Wrappers.<PrepareDetail>lambdaQuery()
                .eq(PrepareDetail::getId, prepareDetail.getId()));
        //找到旧的备料数据所对应的材料申请数据
        ReserveDetail reserveDetail = reserveDetailMapper.selectOne(Wrappers.<ReserveDetail>lambdaQuery()
                .eq(ReserveDetail::getId, prepareDetailOld.getWarehouseReserveDetailId()).eq(ReserveDetail::getPartId, prepareDetailOld.getPartId()));
        if (reserveDetail.getPpoQty().subtract(prepareDetailOld.getPrepareQty()).add(prepareDetail.getPrepareQty()).compareTo(reserveDetail.getResQty()) == 1) {
            throw new RuntimeException("备料数量超过了需求数量,请重新备料");
        }
        //获取旧的备料数据对应实时库存的数据
        Stock stock = stockMapper.selectOne(Wrappers.<Stock>lambdaQuery().eq(Stock::getPartId, prepareDetailOld.getPartId())
                .eq(Stock::getLocationId, prepareDetailOld.getLocationId()).eq(Stock::getPartBatchNo, prepareDetail.getPartBatchNo()).eq(Stock::getSystemNo,prepareDetail.getSystemNo()));
        ReserveMain reserveMain = reserveMainMapper.selectById(reserveDetail.getWarehouseMainId());
        StockInCode stockInCode = stockInCodeMapper.selectById(reserveMain.getResType());
        stockUtils.updateById(stock.getId(), BigDecimal.ZERO, prepareDetail.getPrepareQty().subtract(prepareDetailOld.getPrepareQty()),  BigDecimal.ZERO, BigDecimal.ZERO,reserveMain.getResNo(), stockInCode.getStockCodeName());
        reserveDetail.setPpoQty(reserveDetail.getPpoQty().subtract(prepareDetailOld.getPrepareQty()).add(prepareDetail.getPrepareQty()));
        reserveDetailMapper.updateById(reserveDetail);
        //更新备料数据
        baseMapper.updateById(prepareDetail);
        return true;
    }
 
    @Override
    public void fullSave(PrepareDetail prepareDetail) {
        //获取对应实时库存的数据
        Stock stock = stockMapper.selectOne(Wrappers.<Stock>lambdaQuery().eq(Stock::getPartId, prepareDetail.getPartId())
                .eq(Stock::getLocationId, prepareDetail.getLocationId()).eq(Stock::getPartBatchNo, prepareDetail.getPartBatchNo()).eq(Stock::getSystemNo,prepareDetail.getSystemNo()));
        //获取关于备料关联的零件申请明细的数据
        ReserveDetail reserveDetail = reserveDetailMapper.selectOne(Wrappers.<ReserveDetail>lambdaQuery()
                .eq(ReserveDetail::getId, prepareDetail.getWarehouseReserveDetailId()).eq(ReserveDetail::getPartId, prepareDetail.getPartId()));
        //将新增的明细数量加上
        BigDecimal totalPrepareQty = reserveDetail.getPpoQty() == null ? BigDecimal.ZERO : reserveDetail.getPpoQty();
        if (prepareDetail.getPrepareQty().add(reserveDetail.getPpoQty()).compareTo(reserveDetail.getResQty()) == 1) {
            throw new RuntimeException("备料数量超过了需求数量,请重新备料");
        }
        reserveDetail.setPpoQty(totalPrepareQty.add(prepareDetail.getPrepareQty()));
        reserveDetail.setStatus("已配料");
        reserveDetailMapper.updateById(reserveDetail);
        ReserveMain reserveMain = reserveMainMapper.selectById(reserveDetail.getWarehouseMainId());
        StockInCode stockInCode = stockInCodeMapper.selectById(reserveMain.getResType());
        stockUtils.updateById(stock.getId(), BigDecimal.ZERO, prepareDetail.getPrepareQty(),  BigDecimal.ZERO, BigDecimal.ZERO,reserveMain.getResNo(), stockInCode.getStockCodeName());
        baseMapper.insert(prepareDetail);
 
    }
 
    @Override
    public IPage<List<PrepareDetail>> getPrepare(Page page, QueryWrapper<PrepareDetail> prepareDetail) {
        return baseMapper.getPrepare(page, prepareDetail);
    }
 
    @Override
    public R<IPage<List<PrepareDetailDTO>>> getPrepareByNo(Page page, PrepareDetailDTO prepareDetailDTO) {
        if (prepareDetailDTO.getResNo() == null) {
            return R.failed("请选择领料单号");
        }
        IPage<List<PrepareDetailDTO>> newPrepareDetailDTO = baseMapper.getPrepareByNo(page, prepareDetailDTO);
        if (newPrepareDetailDTO == null) {
            throw new RuntimeException("查不到对应备料明细,请确认领料单号");
        }
        return R.ok(newPrepareDetailDTO);
    }
 
    @Override
    public R<PrepareDetailDTO> pdaPrepareDetailSave(PrepareDetailDTO prepareDetailDTO) {
        if (prepareDetailDTO.getOutQty() == null) {
            return R.failed("请输入出库数量");
        }
        if (prepareDetailDTO.getOutQty().compareTo(BigDecimal.ZERO) != 1) {
            return R.failed("出库数量不能小于等于0");
        }
        //1.先把领料单的所有数据拿到
        PrepareDetail prepareDetail = prepareDetailMapper.selectById(prepareDetailDTO.getId());
        //3.如果出库数量大于了预留数量并且状态为不允许超过预留数量,返回数量超过信息
        if (prepareDetail.getOutQty().add(prepareDetailDTO.getOutQty()).compareTo(prepareDetail.getPrepareQty()) == 1) {
            return R.failed("此领料单出库数量已大于预留数量");
        }
        Stock stock = stockMapper.selectOne(Wrappers.<Stock>lambdaQuery().eq(Stock::getPartId, prepareDetail.getPartId())
                .eq(Stock::getLocationId, prepareDetail.getLocationId()).eq(Stock::getPartBatchNo, prepareDetail.getPartBatchNo()).eq(Stock::getSystemNo,prepareDetail.getSystemNo()));
        if (stock == null) {
            return R.failed("库存不存在,请申请仓库补货");
        }
        ReserveDetail reserveDetail = reserveDetailMapper.selectOne(Wrappers.<ReserveDetail>lambdaQuery()
                .eq(ReserveDetail::getId, prepareDetail.getWarehouseReserveDetailId()).eq(ReserveDetail::getPartId, prepareDetail.getPartId()));
        //2.判断出库数量是否已经存在
        BigDecimal reserveQty = reserveDetail.getOutQty() == null ? BigDecimal.ZERO : reserveDetail.getOutQty();
        BigDecimal outPrepareQty = prepareDetail.getOutQty() == null ? BigDecimal.ZERO : prepareDetail.getOutQty();
        //4.更新领料单的出库数量
        reserveDetail.setOutQty(reserveQty.add(prepareDetailDTO.getOutQty()));
        if (reserveDetail.getOutQty().compareTo(reserveDetail.getPpoQty()) == 0) {
            reserveDetail.setStatus("已拣料");
        }
        reserveDetailMapper.updateById(reserveDetail);
        prepareDetail.setUpdateTime(LocalDateTime.now());
        prepareDetail.setOutQty(outPrepareQty.add(prepareDetailDTO.getOutQty()));
        baseMapper.updateById(prepareDetail);
        //5.判断出库数量是否超过预留数量,不超过直接减去出库数量
        ReserveMain reserveMain = reserveMainMapper.selectById(reserveDetail.getWarehouseMainId());
        StockInCode stockInCode = stockInCodeMapper.selectById(reserveMain.getResType());
        stockUtils.updateById(stock.getId(), prepareDetailDTO.getOutQty().negate(), prepareDetailDTO.getOutQty().negate(), BigDecimal.ZERO, BigDecimal.ZERO, reserveMain.getResNo(), stockInCode.getStockCodeName());
        return R.ok(baseMapper.getPrepareResMain(prepareDetailDTO.getId()));
    }
 
    @Override
    public PrepareDetailDTO getPrepareById(Long id) {
        return baseMapper.getPrepareById(id);
    }
 
    @Override
    public R<IPage<List<PrepareDetailDTO>>> getPrepareDetailByNo(Page page, PrepareDetailDTO prepareDetailDTO) {
        if (prepareDetailDTO.getResNo() == null) {
            return R.failed("请选择领料单号");
        }
        IPage<List<PrepareDetailDTO>> newPrepareDetailDTO = baseMapper.getPrepareDetailByNo(page, prepareDetailDTO);
        if (newPrepareDetailDTO == null) {
            return R.failed("查不到对应备料明细,请确认领料单号");
        }
        return R.ok(newPrepareDetailDTO);
    }
 
    @Override
    public boolean batchSave(PrepareDetail[] prepareDetails) {
        for (PrepareDetail pd : prepareDetails) {
            if (pd.getId() != null && pd.getId() > 0) {
                ReserveDetail reserveDetailByFind = reserveDetailMapper.selectOne(Wrappers.<ReserveDetail>lambdaQuery().eq(ReserveDetail::getPartId, pd.getPartId()).eq(ReserveDetail::getId, pd.getWarehouseReserveDetailId()));
                if (reserveDetailByFind == null) {
                    throw new RuntimeException("材料申请零件不存在");
                }
                PrepareDetail prepareDetailByFind = this.getOne(Wrappers.<PrepareDetail>lambdaQuery().eq(PrepareDetail::getLocationId,pd.getLocationId()).eq(PrepareDetail::getWarehouseReserveDetailId,pd.getWarehouseReserveDetailId())
                        .ne(PrepareDetail::getId,pd.getId()).eq(PrepareDetail::getPartBatchNo,pd.getPartBatchNo()));
                if (prepareDetailByFind != null) {
                    throw new RuntimeException("材料备料重复:" + prepareDetailByFind.getPartId() + "-" + prepareDetailByFind.getLocationId());
                }
                this.fullUpdate(pd);
            }else {
                PrepareDetail prepareDetailByFind = this.getOne(Wrappers.<PrepareDetail>lambdaQuery().eq(PrepareDetail::getLocationId,pd.getLocationId()).
                        eq(PrepareDetail::getWarehouseReserveDetailId,pd.getWarehouseReserveDetailId()).eq(PrepareDetail::getPartBatchNo,pd.getPartBatchNo()));
                if (prepareDetailByFind != null) {
                    throw new RuntimeException("材料备料重复:" + prepareDetailByFind.getPartId() + "-" + prepareDetailByFind.getLocationId());
                }
                this.fullSave(pd);
            }
        }
        return true;
    }
 
    @Override
    public IPage<List<PrepareDetailDTO>> getPrepareByDate(Page page, ReserveMainDTO reserveMainDTO) {
        return baseMapper.getPrepareDetailByDate(page, reserveMainDTO);
    }
}